├── .gitignore ├── CMakeLists.txt ├── COMPILATION.md ├── Display ├── CAboutDlg.cpp ├── CAboutDlg.h ├── CConfigDlg.cpp ├── CConfigDlg.h ├── CEditor.cpp ├── CEditor.h ├── CEditorFindDlg.cpp ├── CEditorFindDlg.h ├── CEventFilterObj.cpp ├── CEventFilterObj.h ├── CFileListWidget.cpp ├── CFileListWidget.h ├── CFindReplaceDlg.cpp ├── CFindReplaceDlg.h ├── CMainWindow.cpp ├── CMainWindow.h ├── CProjectDlg.cpp ├── CProjectDlg.h ├── CProjectListWidget.cpp ├── CProjectListWidget.h ├── CSearchTextBrowser.cpp ├── CSearchTextBrowser.h ├── CSearchTextEdit.cpp ├── CSearchTextEdit.h ├── CSearchWebView.cpp └── CSearchWebView.h ├── LICENSE ├── Model ├── CConfigManager.cpp ├── CConfigManager.h ├── CFileItem.cpp ├── CFileItem.h ├── CFileListModel.cpp ├── CFileListModel.h ├── CFindReplaceModel.cpp ├── CFindReplaceModel.h ├── CProjectItem.cpp ├── CProjectItem.h ├── CProjectListModel.cpp ├── CProjectListModel.h ├── CProjectLoadThread.cpp ├── CProjectLoadThread.h ├── CProjectManager.cpp ├── CProjectManager.h ├── CProjectUpdateThread.cpp ├── CProjectUpdateThread.h ├── CRunCommand.cpp ├── CRunCommand.h ├── qFindReplacer │ ├── qFindReplacer.cpp │ └── qFindReplacer.h └── qTagger │ ├── CSourceFileList.cpp │ ├── CSourceFileList.h │ ├── CTagFileRecord.cpp │ ├── CTagFileRecord.h │ ├── CTagItem.cpp │ ├── CTagItem.h │ ├── CTagResultItem.cpp │ ├── CTagResultItem.h │ ├── qTagger.cpp │ └── qTagger.h ├── README.md ├── Resources ├── Forms │ ├── aboutDialog.ui │ ├── configDialog.ui │ ├── editor.ui │ ├── editorFindDialog.ui │ ├── findReplaceDialog.ui │ ├── groupDialog.ui │ ├── mainWindow.ui │ └── projectDialog.ui ├── Icons │ ├── 22x22 │ │ ├── code-class.png │ │ ├── document-new-4.png │ │ ├── document-open-6.png │ │ ├── document-open-folder.png │ │ ├── edit-4.png │ │ ├── edit-add-4.png │ │ ├── edit-copy-4.png │ │ ├── edit-remove-3.png │ │ ├── gtk-about.png │ │ ├── gtk-cancel.png │ │ ├── gtk-delete.png │ │ ├── gtk-execute.png │ │ ├── gtk-new.png │ │ ├── gtk-ok.png │ │ ├── gtk-properties.png │ │ ├── gtk-redo-ltr.png │ │ ├── gtk-refresh.png │ │ ├── insert-link-2.png │ │ ├── view-process-all.png │ │ ├── xconsole-2.png │ │ └── zoom-3.png │ ├── 48x48 │ │ ├── application-x-gnome-saved-search.png │ │ ├── applications-graphics-5.png │ │ ├── applications-system.png │ │ └── forward.png │ ├── appIcons.rc │ ├── graphics.ico │ ├── graphics2.ico │ ├── graphics3.ico │ └── text-x-preview.ico ├── Images │ ├── copy.png │ ├── cut.png │ ├── file.png │ ├── graphics16x16.png │ ├── graphics2.png │ ├── graphics3.png │ ├── graphics32x32.png │ ├── group.png │ ├── new.png │ ├── open.png │ ├── paste.png │ ├── project.png │ ├── save.png │ └── symbol.png ├── app.qrc └── webview.qrc ├── Screencast └── Usage.gif ├── Screenshot ├── blink_codesearch.png ├── blink_filelisting.png ├── blink_multiple_lines.png ├── blink_multiple_symbols.png ├── blink_regular_expression.png ├── blink_replaceinfiles.png ├── usage_drop_folder.png ├── usage_load_project.png └── usage_new_project.png ├── Setup └── blinkSetup.iss ├── Storage ├── CDbmStorageHandler.cpp ├── CDbmStorageHandler.h ├── CXmlStorageHandler.cpp ├── CXmlStorageHandler.h └── IStorageHandler.h ├── Tool └── linuxdeployqt-continuous-x86_64.AppImage ├── Utils ├── CUtils.cpp ├── CUtils.h ├── commonType.h ├── plugins │ └── dbmplugin │ │ ├── dbmplugin.cpp │ │ ├── dbmplugin.h │ │ └── dbmplugin.pro ├── qTag │ ├── interfaces.h │ ├── keyword.txt │ ├── pyclean.py │ ├── qTag.cpp │ ├── qTag.pro │ ├── qTagApp.cpp │ ├── qTagApp.h │ └── test │ │ ├── TestCRecordPool.cpp │ │ ├── TestCRecordPool.h │ │ └── TestCRecordPool.pro └── test │ ├── TestCUtils.cpp │ ├── TestCUtils.h │ └── TestCUtils.pro ├── app └── share │ └── metainfo │ ├── io.github.ychclone.blink.metainfo.xml │ └── io.github.ychclone.blink.png ├── appveyor.yml ├── blink.ini ├── blink.pro ├── blinkAppImage ├── .DirIcon └── usr │ └── share │ ├── applications │ └── blink.desktop │ └── icons │ └── hicolor │ └── 128x128 │ └── blink.png ├── build ├── Html │ └── style.css └── keyword.txt ├── clean_debug.py ├── clean_makefile.py ├── clean_release.py ├── flatpak ├── io.github.ychclone.blink.yml └── qscintilla-lib-paths.patch └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.dylib 11 | 12 | # Qt-es 13 | object_script.*.Release 14 | object_script.*.Debug 15 | *_plugin_import.cpp 16 | /.qmake.cache 17 | /.qmake.stash 18 | *.pro.user 19 | *.pro.user.* 20 | *.qbs.user 21 | *.qbs.user.* 22 | *.moc 23 | moc_*.cpp 24 | moc_*.h 25 | qrc_*.cpp 26 | ui_*.h 27 | *.qmlc 28 | *.jsc 29 | Makefile* 30 | *build-* 31 | 32 | # Qt unit tests 33 | target_wrapper.* 34 | 35 | # QtCreator 36 | *.autosave 37 | 38 | # QtCreator Qml 39 | *.qmlproject.user 40 | *.qmlproject.user.* 41 | 42 | # QtCreator CMake 43 | CMakeLists.txt.user* 44 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1.0) 2 | 3 | project(blink VERSION 1.0.0 LANGUAGES CXX) 4 | 5 | set(CMAKE_CXX_STANDARD 11) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | 8 | set(CMAKE_AUTOMOC ON) 9 | set(CMAKE_AUTORCC ON) 10 | set(CMAKE_AUTOUIC ON) 11 | 12 | if(CMAKE_VERSION VERSION_LESS "3.7.0") 13 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 14 | endif() 15 | 16 | find_package(Qt6 COMPONENTS Widgets Xml Network REQUIRED) 17 | 18 | set(CMAKE_AUTOUIC_SEARCH_PATHS Resources/Forms) 19 | 20 | include_directories(. Utils /opt/QScintilla_src-2.14.1/src) 21 | 22 | link_directories (/opt/QScintilla_src-2.14.1/src) 23 | 24 | add_executable(blink 25 | Resources/Forms/mainWindow.ui 26 | Resources/Forms/editor.ui 27 | Resources/Forms/projectDialog.ui 28 | Resources/Forms/aboutDialog.ui 29 | Resources/Forms/configDialog.ui 30 | Resources/Forms/findReplaceDialog.ui 31 | Resources/Forms/editorFindDialog.ui 32 | 33 | Resources/app.qrc 34 | Resources/Icons/appIcons.rc 35 | 36 | main.cpp 37 | Utils/CUtils.cpp 38 | Display/CMainWindow.cpp 39 | Display/CEditor.cpp 40 | Display/CEditorFindDlg.cpp 41 | Display/CProjectDlg.cpp 42 | Display/CAboutDlg.cpp 43 | Display/CProjectListWidget.cpp 44 | Display/CFileListWidget.cpp 45 | Display/CConfigDlg.cpp 46 | Display/CEventFilterObj.cpp 47 | Display/CSearchTextBrowser.cpp 48 | Display/CSearchTextEdit.cpp 49 | Display/CFindReplaceDlg.cpp 50 | Model/qTagger/CTagItem.cpp 51 | Model/qTagger/CTagFileRecord.cpp 52 | Model/qTagger/CTagResultItem.cpp 53 | Model/qTagger/qTagger.cpp 54 | Model/qTagger/CSourceFileList.cpp 55 | Model/qFindReplacer/qFindReplacer.cpp 56 | Model/CProjectListModel.cpp 57 | Model/CFileListModel.cpp 58 | Model/CProjectManager.cpp 59 | Model/CProjectUpdateThread.cpp 60 | Model/CProjectLoadThread.cpp 61 | Model/CConfigManager.cpp 62 | Model/CProjectItem.cpp 63 | Model/CFileItem.cpp 64 | Model/CRunCommand.cpp 65 | Model/CFindReplaceModel.cpp 66 | Storage/CXmlStorageHandler.cpp 67 | 68 | ) 69 | 70 | target_link_libraries(blink Qt6::Widgets Qt6::Xml Qt6::Network qscintilla2_qt6) 71 | 72 | set(CMAKE_INSTALL_PREFIX /app/bin) 73 | 74 | install(TARGETS blink 75 | DESTINATION ${CMAKE_INSTALL_PREFIX} 76 | ) 77 | 78 | 79 | -------------------------------------------------------------------------------- /COMPILATION.md: -------------------------------------------------------------------------------- 1 | # Compilation (QMake Windows) 2 | 3 | 1. Download Qt Open Source installer: 4 | https://www.qt.io/download-open-source 5 | 6 | 2. Install Qt 6.4.2 (Mingw 64 bit and its tool) 7 | 8 | 3. Set Qt and mingw 64 binaries path 9 | 10 | ``` 11 | set QTDIR=C:\Qt6\6.4.2\mingw_64 12 | set PATH=%PATH%;%QTDIR%\bin;C:\Qt6\Tools\mingw1120_64\bin 13 | ``` 14 | 15 | 4. Download QScintilla 2.14.1 and install 16 | https://riverbankcomputing.com/software/qscintilla/download 17 | 18 | ``` 19 | cd QScintilla_src-2.14.1/src 20 | qmake qscintilla.pro 21 | make 22 | make install 23 | ``` 24 | 25 | 5. cd blink 26 | 6. qmake blink.pro 27 | 7. mingw32-make 28 | 29 | # Compilation (QMake Linux) 30 | 31 | 1. Download Qt Open Source installer: 32 | https://www.qt.io/download-open-source 33 | 34 | 2. Install Qt 6.6.1 35 | 36 | 3. Link qmake to /usr/bin/qmake 37 | ``` 38 | sudo ln -s /home/ychclone/Qt/6.6.1/gcc_64/bin/qmake /usr/bin/qmake 39 | ``` 40 | 41 | 4. Download QScintilla 2.14.1 and install 42 | https://riverbankcomputing.com/software/qscintilla/download 43 | 44 | Set to static library for qscintilla 45 | ``` 46 | qscintilla.pro: 47 | CONFIG += staticlib 48 | 49 | ``` 50 | 51 | Compile and install QScintilla 52 | ``` 53 | cd QScintilla_src-2.14.1/src 54 | qmake qscintilla.pro 55 | make 56 | make install 57 | ``` 58 | 59 | 5. Install dependencies 60 | ``` 61 | sudo apt install libgl1-mesa-dev 62 | sudo apt-get install libxcb-cursor0 63 | ``` 64 | 65 | 6. Build in QMake 66 | 67 | ``` 68 | qmake blink.pro 69 | make 70 | ``` 71 | 72 | # AppImage 73 | 74 | 1. Download linuxdeployqt-7-x86_64.AppImage: 75 | https://github.com/probonopd/linuxdeployqt/releases 76 | 77 | 2. chmod u+x linuxdeployqt-7-x86_64.AppImage 78 | 3. copy compiled blink executable to blinkAppImage/usr/bin/ 79 | 4. ./linuxdeployqt-7-x86_64.AppImage blinkAppImage/usr/share/applications/blink.desktop -verbose=2 -appimage -extra-plugins=iconengines,platformthemes/libqgtk3.so 80 | 81 | -------------------------------------------------------------------------------- /Display/CAboutDlg.cpp: -------------------------------------------------------------------------------- 1 | #include "CAboutDlg.h" 2 | 3 | CAboutDlg::CAboutDlg(QWidget* parent) 4 | : QDialog(parent) 5 | { 6 | setupUi(this); 7 | } -------------------------------------------------------------------------------- /Display/CAboutDlg.h: -------------------------------------------------------------------------------- 1 | #ifndef CABOUTDLG_H 2 | #define CABOUTDLG_H 3 | 4 | #include 5 | #include "ui_aboutDialog.h" 6 | 7 | class CAboutDlg : public QDialog, private Ui::aboutDialog 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | CAboutDlg(QWidget* parent = 0); 13 | virtual ~CAboutDlg() {} 14 | }; 15 | #endif // CABOUTDLG_H 16 | 17 | 18 | -------------------------------------------------------------------------------- /Display/CConfigDlg.h: -------------------------------------------------------------------------------- 1 | #ifndef CCONFIGDLG_H 2 | #define CCONFIGDLG_H 3 | 4 | #include 5 | #include "ui_configDialog.h" 6 | 7 | class CConfigDlg : public QDialog, private Ui::configDialog 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | CConfigDlg(QWidget* parent = 0); 13 | 14 | virtual ~CConfigDlg() {}; 15 | 16 | QFont getProjectDefaultFont(); 17 | QFont getSymbolDefaultFont(); 18 | QFont getSymbolAutoCompleteDefaultFont(); 19 | 20 | private slots: 21 | void changePage(QListWidgetItem *current, QListWidgetItem *previous); 22 | void on_okButton_clicked(); 23 | void on_cancelButton_clicked(); 24 | void on_applyButton_clicked(); 25 | 26 | void on_defaultEditor_toolBn_clicked(); 27 | void on_projectFont_toolBn_clicked(); 28 | 29 | void on_symbolFont_toolBn_clicked(); 30 | void on_symbolAutoCompleteFont_toolBn_clicked(); 31 | 32 | void on_editorFont_toolBn_clicked(); 33 | 34 | void on_tmpDir_toolBn_clicked(); 35 | 36 | void configContentChanged(); 37 | 38 | private: 39 | void createActions(); 40 | 41 | void loadSetting(); 42 | void saveSetting(); 43 | 44 | QFont projectDefaultFont_; 45 | QFont symbolDefaultFont_; 46 | QFont symbolAutoCompleteDefaultFont_; 47 | QFont editorDefaultFont_; 48 | 49 | 50 | }; 51 | 52 | #endif // CCONFIGDLG_H 53 | -------------------------------------------------------------------------------- /Display/CEditor.h: -------------------------------------------------------------------------------- 1 | #ifndef CEDITOR_H 2 | #define CEDITOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ui_editor.h" 12 | 13 | #include 14 | #include 15 | 16 | class QsciScintilla; 17 | class CMainWindow; 18 | 19 | struct EditorTab 20 | { 21 | QsciScintilla* textEdit; 22 | QsciLexer* lexer; 23 | }; 24 | 25 | class CEditor : public QWidget, private Ui::editor 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | CEditor(CMainWindow* parent); 31 | 32 | virtual ~CEditor() {}; 33 | 34 | void newFile(); 35 | void closeFile(); 36 | void save(); 37 | void saveAs(); 38 | void openFile(); 39 | 40 | void loadFileWithLineNum(const QString& filePath, int lineNumber); 41 | void loadFileWithLineNumNewTab(const QString& filePath, int lineNumber); 42 | 43 | QsciLexer* getLexer(const QString& fileName); 44 | void setTextEdit(QsciScintilla* textEdit); 45 | 46 | int loadFile(const QString& filePath); 47 | void loadFileNewTab(const QString& filePath); 48 | 49 | void updateAllEditorFont(); 50 | 51 | void findText(const QString& text, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 52 | void replaceText(const QString& findText, const QString& replaceText, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 53 | void replaceAllText(const QString& findText, const QString& replaceText, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 54 | 55 | void goToLine(int line); 56 | void textEditGoToLine(QsciScintilla *textEdit, int line); 57 | void cut(); 58 | void copy(); 59 | void paste(); 60 | void undo(); 61 | void redo(); 62 | 63 | void resetNavHistory(); 64 | 65 | signals: 66 | void statusLeft(const QString& status); 67 | void statusMiddle(const QString& status); 68 | void statusRight(const QString& status); 69 | 70 | private slots: 71 | void closeAllTabsButCurrent(const QPoint &pos); 72 | void closeAllTabsToLeft(const QPoint &pos); 73 | void closeAllTabsToRight(const QPoint &pos); 74 | void copyFilePath(const QPoint &pos); 75 | void copyFileName(const QPoint &pos); 76 | void copyFile(const QPoint &pos); 77 | void reloadFileFromTab(const QPoint &pos); 78 | 79 | private: 80 | void closeEvent(QCloseEvent *event); 81 | 82 | void saveWidgetPosition(); 83 | 84 | void createActions(QsciScintilla* textEdit); 85 | 86 | void textEditModified(); 87 | void handleCursorPositionChanged(int line, int index); 88 | 89 | void setEditorFont(QsciLexer* lexer); 90 | 91 | void saveFile(const QString &fileName); 92 | 93 | QString filePathInTab(int tabIndex); 94 | 95 | void tabChanged(int tabIndex); 96 | void closeCurrentTab(const QPoint &pos); 97 | void closeTab(int tabIndex); 98 | 99 | void tabContextMenuEvent(const QPoint &pos); 100 | 101 | void setupFileWatcher(const QString& filePath); 102 | 103 | void beginFileModification(const QString& filePath); 104 | void endFileModification(const QString& filePath); 105 | 106 | void reloadFile(const QString& filePath); 107 | void onEndModificationTimeout(); 108 | void onEndNavigationTimeout(); 109 | 110 | void fileChanged(const QString& path); 111 | 112 | QMap editorTabMap_; // key: source filepath 113 | CMainWindow* parent_; 114 | 115 | int currentNewFileNumber_; 116 | 117 | QFileSystemWatcher fileWatcher_; 118 | QSet filesBeingModified_; 119 | 120 | QTimer* endModificationTimer_; 121 | QTimer* endNavigationTimer_; 122 | 123 | QVector> navHistory_; 124 | int currentHistoryIndex_; 125 | 126 | bool isNavigatingHistory_; 127 | QSet filesAlreadyPrompted_; 128 | 129 | void addToNavHistory(const QString& filePath, int line); 130 | 131 | public slots: 132 | void goForward(); 133 | void goBackward(); 134 | 135 | signals: 136 | void updateGoForwardBackwardActions(bool canGoForward, bool canGoBackward); 137 | }; 138 | 139 | #endif // CEDITOR_H 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Display/CEditorFindDlg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #ifdef Q_OS_WIN 9 | #include 10 | #endif 11 | 12 | #include "CEditorFindDlg.h" 13 | 14 | CEditorFindDlg::CEditorFindDlg(QWidget* parent) 15 | : QDialog(parent) 16 | { 17 | setupUi(this); 18 | 19 | // add status bar 20 | //statusbar = new QStatusBar(this); 21 | //statusBarLayout->addWidget(statusbar); 22 | 23 | createActions(); 24 | } 25 | 26 | void CEditorFindDlg::setLineEditFocus() 27 | { 28 | find_lineEdit->setFocus(); 29 | } 30 | 31 | void CEditorFindDlg::createActions() 32 | { 33 | connect(find_lineEdit, &QLineEdit::textChanged, this, &CEditorFindDlg::on_findButton_clicked); 34 | connect(replaceFind_lineEdit, &QLineEdit::textChanged, this, &CEditorFindDlg::on_replaceFindButton_clicked); 35 | } 36 | 37 | void CEditorFindDlg::on_findButton_clicked() 38 | { 39 | emit findText(find_lineEdit->text(), matchWholeWord_checkBox->isChecked(), caseSensitive_checkBox->isChecked(), regularExpression_checkBox->isChecked()); 40 | } 41 | 42 | void CEditorFindDlg::on_replaceFindButton_clicked() 43 | { 44 | emit findText(replaceFind_lineEdit->text(), replaceMatchWholeWord_checkBox->isChecked(), replaceCaseSensitive_checkBox->isChecked(), replaceRegularExpression_checkBox->isChecked()); 45 | } 46 | 47 | void CEditorFindDlg::on_replaceButton_clicked() 48 | { 49 | emit replaceText(replaceFind_lineEdit->text(), replace_lineEdit->text(), replaceMatchWholeWord_checkBox->isChecked(), replaceCaseSensitive_checkBox->isChecked(), replaceRegularExpression_checkBox->isChecked()); 50 | } 51 | 52 | void CEditorFindDlg::on_replaceAllButton_clicked() 53 | { 54 | emit replaceAllText(replaceFind_lineEdit->text(), replace_lineEdit->text(), replaceMatchWholeWord_checkBox->isChecked(), replaceCaseSensitive_checkBox->isChecked(), replaceRegularExpression_checkBox->isChecked()); 55 | } 56 | 57 | void CEditorFindDlg::on_replaceCancelButton_clicked() 58 | { 59 | this->done(QDialog::Rejected); 60 | } 61 | 62 | void CEditorFindDlg::on_cancelButton_clicked() 63 | { 64 | this->done(QDialog::Rejected); 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Display/CEditorFindDlg.h: -------------------------------------------------------------------------------- 1 | #ifndef CEDITOR_FIND_DLG_H 2 | #define CEDITOR_FIND_DLG_H 3 | 4 | #include 5 | #include 6 | 7 | #include "ui_editorFindDialog.h" 8 | 9 | class CEditorFindDlg : public QDialog, private Ui::editorFindDialog 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | CEditorFindDlg(QWidget* parent); 15 | virtual ~CEditorFindDlg() {}; 16 | 17 | void setLineEditFocus(); 18 | 19 | signals: 20 | void findText(const QString& text, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 21 | void replaceText(const QString& findText, const QString& replaceText, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 22 | void replaceAllText(const QString& findText, const QString& replaceText, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 23 | 24 | private slots: 25 | void on_findButton_clicked(); 26 | void on_cancelButton_clicked(); 27 | void on_replaceFindButton_clicked(); 28 | void on_replaceButton_clicked(); 29 | void on_replaceAllButton_clicked(); 30 | 31 | void on_replaceCancelButton_clicked(); 32 | 33 | private: 34 | void createActions(); 35 | 36 | QStatusBar *statusbar; 37 | 38 | }; 39 | 40 | #endif // CEDITOR_FIND_DLG_H 41 | 42 | -------------------------------------------------------------------------------- /Display/CEventFilterObj.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "Display/CMainWindow.h" 8 | #include "Model/CConfigManager.h" 9 | #include "CEventFilterObj.h" 10 | 11 | bool CEventFilterObj::eventFilter(QObject *obj, QEvent *event) 12 | { 13 | QPoint p; 14 | bool bAutoHideMenu; 15 | CConfigManager* confManager; 16 | QKeyEvent *keyEvent; 17 | QMouseEvent *mouseEvent; 18 | 19 | // only process for the key press and mouse press event 20 | switch (event->type()) { 21 | case QEvent::KeyPress: 22 | case QEvent::MouseButtonPress: 23 | break; 24 | default: 25 | return QObject::eventFilter(obj, event); 26 | } 27 | 28 | confManager = CConfigManager::getInstance(); 29 | 30 | bAutoHideMenu = confManager->getAppSettingValue("AutoHideMenu").toBool(); 31 | 32 | // only hide/show menubar if active window is the main window 33 | if ((bAutoHideMenu) && (strcmp(QApplication::activeWindow()->metaObject()->className(), "CMainWindow") == 0)) { 34 | CMainWindow *mainWindow = static_cast (QApplication::activeWindow()); 35 | 36 | switch (event->type()) { 37 | case QEvent::KeyPress: 38 | keyEvent = static_cast(event); 39 | 40 | if (keyEvent->key() == Qt::Key_Alt) { 41 | if (mainWindow->menuBar()->isHidden()) { 42 | mainWindow->menuBar()->show(); 43 | } 44 | } else { 45 | if (!(mainWindow->menuBar()->isHidden())) { 46 | // only hide menu if menubar or menu not selected 47 | if ((strcmp(QApplication::focusWidget()->metaObject()->className(), "QMenu") == -1) && 48 | (strcmp(QApplication::focusWidget()->metaObject()->className(), "QMenuBar") == -1)) { 49 | mainWindow->menuBar()->hide(); 50 | } 51 | } 52 | } 53 | break; 54 | 55 | case QEvent::MouseButtonPress: 56 | mouseEvent = static_cast(event); 57 | 58 | p = mainWindow->menuBar()->mapFromGlobal(mouseEvent->globalPos()); 59 | 60 | // hide menuBar only when not hidden 61 | if (!(mainWindow->menuBar()->isHidden())) { 62 | // hide menuBar only when mouse not in menuBar area 63 | if (!(mainWindow->menuBar()->rect().contains(p))) { 64 | mainWindow->menuBar()->hide(); 65 | } 66 | } 67 | 68 | break; 69 | 70 | default: 71 | break; 72 | } 73 | 74 | return QObject::eventFilter(obj, event); 75 | } else { 76 | return QObject::eventFilter(obj, event); 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /Display/CEventFilterObj.h: -------------------------------------------------------------------------------- 1 | #ifndef CEVENTFILTEROBJ_H 2 | #define CEVENTFILTEROBJ_H 3 | 4 | #include 5 | 6 | class CEventFilterObj : public QObject 7 | { 8 | Q_OBJECT 9 | 10 | protected: 11 | bool eventFilter(QObject *obj, QEvent *event); 12 | }; 13 | 14 | #endif // CEVENTFILTEROBJ_H 15 | -------------------------------------------------------------------------------- /Display/CFileListWidget.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "CFileListWidget.h" 9 | 10 | CFileListWidget::CFileListWidget(QWidget *parent) 11 | : QTreeView(parent) 12 | { 13 | QFont currentFont = static_cast (this)->font(); 14 | fileFontSize_ = currentFont.pointSize(); 15 | } 16 | 17 | void CFileListWidget::setFileListModel(CFileListModel *fileListModel) 18 | { 19 | fileListModel_ = fileListModel; 20 | } 21 | 22 | void CFileListWidget::mousePressEvent(QMouseEvent *event) 23 | { 24 | if (event->button() == Qt::LeftButton) { 25 | dragStartPosition_ = event->pos(); 26 | } 27 | QTreeView::mousePressEvent(event); 28 | } 29 | 30 | void CFileListWidget::mouseReleaseEvent(QMouseEvent* event) 31 | { 32 | if (event->button() == Qt::LeftButton) { 33 | emit fileItemTriggered(); 34 | } 35 | QTreeView::mouseReleaseEvent(event); 36 | } 37 | 38 | void CFileListWidget::keyPressEvent(QKeyEvent* event) 39 | { 40 | if (event->key() == Qt::Key_Return) { 41 | emit fileItemTriggered(); 42 | } else if ((event->key() == Qt::Key_Equal) && (event->modifiers() == Qt::ControlModifier)) { 43 | fileZoomIn(); 44 | } else if ((event->key() == Qt::Key_Minus) && (event->modifiers() == Qt::ControlModifier)) { 45 | fileZoomOut(); 46 | } 47 | QTreeView::keyPressEvent(event); 48 | } 49 | 50 | void CFileListWidget::updateOutputFont(const QFont& outputFont) 51 | { 52 | QFont currentFont = static_cast (this)->font(); 53 | 54 | if (currentFont != outputFont) { 55 | static_cast (this)->setFont(outputFont); 56 | 57 | fileFontSize_ = outputFont.pointSize(); 58 | updateFileListWidget(); 59 | } 60 | } 61 | 62 | 63 | QStringList CFileListWidget::getSelectedItemNameList() 64 | { 65 | QModelIndexList indexSelectedList; 66 | QModelIndex indexSelected, mappedIndex; 67 | int rowSelected; 68 | QStandardItem* itemSelected; 69 | 70 | QString fileItemName; 71 | QStringList fileItemNameList; 72 | 73 | QSortFilterProxyModel* proxyModel; 74 | QItemSelectionModel* selectModel; 75 | 76 | proxyModel = static_cast (model()); 77 | selectModel = static_cast (selectionModel()); 78 | 79 | // get selected items index list 80 | indexSelectedList = selectModel->selectedIndexes(); 81 | 82 | foreach (indexSelected, indexSelectedList) { 83 | // map back from proxy model 84 | mappedIndex = proxyModel->mapToSource(indexSelected); 85 | 86 | rowSelected = mappedIndex.row(); 87 | 88 | if (indexSelected.isValid()) { 89 | itemSelected = fileListModel_->item(rowSelected, 0); 90 | if (itemSelected != 0) { 91 | fileItemName = itemSelected->text(); 92 | }; 93 | } 94 | 95 | // as all items in the same row with differnt columns will also be returned in selectedIndexes 96 | if (!fileItemNameList.contains(fileItemName)) { 97 | // not add output name to the list if already added 98 | fileItemNameList += fileItemName; 99 | } 100 | } 101 | 102 | return fileItemNameList; 103 | } 104 | 105 | void CFileListWidget::mouseMoveEvent(QMouseEvent *event) 106 | { 107 | if (!(event->buttons() & Qt::LeftButton)) { 108 | return; 109 | } 110 | if ((event->pos() - dragStartPosition_).manhattanLength() < QApplication::startDragDistance()) { 111 | return; 112 | } 113 | 114 | QList urlList; 115 | QDrag *drag = new QDrag(this); 116 | QMimeData *mimeData = new QMimeData; 117 | 118 | QString filePath; 119 | QStringList filePathList; 120 | 121 | filePathList = getSelectedItemNameList(); 122 | 123 | foreach (filePath, filePathList) { 124 | qDebug() << filePath; 125 | QUrl url = QUrl::fromLocalFile(filePath); 126 | urlList.append(url); 127 | } 128 | 129 | mimeData->setUrls(urlList); 130 | drag->setMimeData(mimeData); 131 | 132 | Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction); 133 | 134 | QTreeView::mouseMoveEvent(event); 135 | } 136 | 137 | void CFileListWidget::updateFileListWidget() 138 | { 139 | resizeColumnToContents(0); 140 | resizeColumnToContents(1); 141 | resizeColumnToContents(2); 142 | } 143 | 144 | void CFileListWidget::fileZoomIn() 145 | { 146 | fileFontSize_++; 147 | QFont fnt = static_cast (this)->font(); 148 | fnt.setPointSize(fileFontSize_); 149 | static_cast (this)->setFont(fnt); 150 | 151 | updateFileListWidget(); 152 | } 153 | 154 | void CFileListWidget::fileZoomOut() 155 | { 156 | if (fileFontSize_ > 1) { 157 | fileFontSize_--; 158 | QFont fnt = static_cast (this)->font(); 159 | fnt.setPointSize(fileFontSize_); 160 | static_cast (this)->setFont(fnt); 161 | } 162 | 163 | updateFileListWidget(); 164 | } 165 | 166 | 167 | void CFileListWidget::wheelEvent(QWheelEvent *e) 168 | { 169 | /* YCH modified (begin), commented temporary */ 170 | /* 171 | if (e->modifiers() == Qt::ControlModifier) { 172 | e->accept(); 173 | if (e->delta() > 0) { 174 | fileZoomIn(); 175 | } else { 176 | fileZoomOut(); 177 | } 178 | } 179 | */ 180 | /* YCH modified (end), commented temporary */ 181 | QTreeView::wheelEvent(e); 182 | } 183 | 184 | 185 | -------------------------------------------------------------------------------- /Display/CFileListWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef CFILE_LIST_WIDGET_H 2 | #define CFILE_LIST_WIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "Model/CFileListModel.h" 11 | 12 | class CFileListWidget : public QTreeView 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | CFileListWidget(QWidget *parent = 0); 18 | 19 | void setFileListModel(CFileListModel *outputModel); 20 | 21 | void mousePressEvent(QMouseEvent *event); 22 | 23 | void mouseReleaseEvent(QMouseEvent* event); 24 | void keyPressEvent(QKeyEvent* event); 25 | 26 | void updateOutputFont(const QFont& outputFont); 27 | 28 | void mouseMoveEvent(QMouseEvent *event); 29 | 30 | void wheelEvent(QWheelEvent *e); 31 | 32 | QPoint dragStartPosition_; 33 | 34 | QStringList getSelectedItemNameList(); 35 | 36 | signals: 37 | void fileItemTriggered(); 38 | 39 | private: 40 | void updateFileListWidget(); 41 | void fileZoomIn(); 42 | void fileZoomOut(); 43 | 44 | CFileListModel* fileListModel_; 45 | 46 | long fileFontSize_; 47 | 48 | }; 49 | 50 | #endif // CFILE_LIST_WIDGET_H 51 | -------------------------------------------------------------------------------- /Display/CFindReplaceDlg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #ifdef Q_OS_WIN 13 | #include 14 | #endif 15 | 16 | #include "CFindReplaceDlg.h" 17 | 18 | #include "Model/CConfigManager.h" 19 | 20 | CFindReplaceDlg::CFindReplaceDlg(QWidget* parent, CFindReplaceModel* findReplaceModel) 21 | : QDialog(parent) 22 | { 23 | setupUi(this); 24 | 25 | progressBar->setMinimum(0); 26 | progressBar->setMaximum(100); 27 | 28 | // connect slot only after when dialog has already been loaded and initial content filled in 29 | progressBar->hide(); 30 | 31 | findReplaceModel_ = findReplaceModel; 32 | 33 | fileListView->setModel(findReplaceModel_->getFileListModel()); 34 | 35 | // add status bar 36 | statusbar = new QStatusBar(this); 37 | statusBarLayout->addWidget(statusbar); 38 | 39 | QStringList fileList = findReplaceModel_->getFileList(); 40 | statusbar->showMessage("Total " + QString::number(fileList.size()) + " files."); 41 | 42 | // create actions need to be after setModel 43 | createActions(); 44 | } 45 | 46 | void CFindReplaceDlg::createActions() 47 | { 48 | connect(findReplaceModel_->getFileListModel(), SIGNAL(itemChanged(QStandardItem *)), this, SLOT(on_fileList_itemChanged(QStandardItem *))); 49 | 50 | connect(actionFileEdit, SIGNAL(triggered()), this, SLOT(on_fileEditPressed())); 51 | } 52 | 53 | void CFindReplaceDlg::setFindLineEdit(QString findStr) 54 | { 55 | find_lineEdit->setText(findStr); 56 | } 57 | 58 | void CFindReplaceDlg::on_replaceButton_clicked() 59 | { 60 | QStringList fileList = findReplaceModel_->getFileList(); 61 | 62 | int i = 0; 63 | int fileTotal = fileList.size(); 64 | 65 | int replacedFileCount = 0; 66 | long totalMatchCount = 0; 67 | long matchCount = 0; 68 | 69 | // only letter or number or underscore for match whole word 70 | if (matchWholeWord_checkBox->isChecked()) { 71 | bool bLetterNumOrUnderscore = true; 72 | 73 | for (i = 0; i < find_lineEdit->text().size(); i++) { 74 | if (!(find_lineEdit->text().at(i).isLetterOrNumber() || find_lineEdit->text().at(i) == QChar('_'))) { 75 | bLetterNumOrUnderscore = false; 76 | break; 77 | } 78 | } 79 | 80 | if (!bLetterNumOrUnderscore) { 81 | QMessageBox::information(this, "File Replaces", "Only letter, number or underscore is supported for match whole word", QMessageBox::Ok); 82 | return; 83 | } 84 | } 85 | 86 | progressBar->show(); 87 | for (i = 0; i < fileTotal; i++) { 88 | matchCount = findReplacer_.replaceInFile(find_lineEdit->text(), replace_lineEdit->text(), fileList[i], caseSensitive_checkBox->isChecked(), matchWholeWord_checkBox->isChecked(), regularExpression_checkBox->isChecked()); 89 | if (matchCount > 0) { 90 | totalMatchCount += matchCount; 91 | replacedFileCount++; 92 | } 93 | 94 | progressBar->setValue(static_cast (static_cast (i + 1) / fileTotal * 100)); 95 | } 96 | 97 | statusbar->showMessage("Replaced " + QString::number(totalMatchCount) + " times, " + QString::number(replacedFileCount) + " files."); 98 | } 99 | 100 | void CFindReplaceDlg::on_cancelButton_clicked() 101 | { 102 | this->done(QDialog::Rejected); 103 | } 104 | 105 | void CFindReplaceDlg::showFileSelectedInStatusBar() 106 | { 107 | QStringList fileList = findReplaceModel_->getFileList(); 108 | statusbar->showMessage("Total " + QString::number(fileList.size()) + " files."); 109 | } 110 | 111 | void CFindReplaceDlg::on_selectAllButton_clicked() 112 | { 113 | findReplaceModel_->selectAllFiles(); 114 | 115 | showFileSelectedInStatusBar(); 116 | } 117 | 118 | void CFindReplaceDlg::on_clearAllButton_clicked() 119 | { 120 | findReplaceModel_->clearSelectAllFiles(); 121 | 122 | showFileSelectedInStatusBar(); 123 | } 124 | 125 | void CFindReplaceDlg::on_fileList_itemChanged(QStandardItem *item) 126 | { 127 | showFileSelectedInStatusBar(); 128 | } 129 | 130 | void CFindReplaceDlg::on_fileEditPressed() 131 | { 132 | QString executeDir; 133 | QString editFilename; 134 | 135 | QString selectedFileName = getSelectedFile(); 136 | 137 | QFileInfo fileInfo(selectedFileName); 138 | executeDir = fileInfo.absoluteDir().absolutePath(); 139 | 140 | QString consoleCommnad = CConfigManager::getInstance()->getAppSettingValue("DefaultEditor").toString(); 141 | 142 | #ifdef Q_OS_WIN 143 | editFilename = "\"" + selectedFileName + "\""; 144 | #else 145 | editFilename = selectedFileName; 146 | #endif 147 | 148 | #ifdef Q_OS_WIN 149 | QString excuteMethod = "open"; 150 | 151 | ShellExecute(NULL, reinterpret_cast(excuteMethod.utf16()), reinterpret_cast(consoleCommnad.utf16()), reinterpret_cast (editFilename.utf16()), reinterpret_cast(executeDir.utf16()), SW_NORMAL); 152 | #else 153 | QProcess::startDetached(consoleCommnad, QStringList(editFilename)); 154 | #endif 155 | } 156 | 157 | QString CFindReplaceDlg::getSelectedFile() 158 | { 159 | QModelIndex index = fileListView->currentIndex(); 160 | QString fileName = index.data(Qt::DisplayRole).toString(); 161 | 162 | return fileName; 163 | } 164 | 165 | void CFindReplaceDlg::contextMenuEvent(QContextMenuEvent* event) 166 | { 167 | QPoint p; 168 | 169 | p = fileListView->mapFromGlobal(event->globalPos()); 170 | 171 | if (fileListView->rect().contains(p)) { 172 | QMenu menu(this); 173 | 174 | menu.addAction(actionFileEdit); 175 | 176 | menu.exec(event->globalPos()); 177 | } 178 | } 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /Display/CFindReplaceDlg.h: -------------------------------------------------------------------------------- 1 | #ifndef CFIND_REPLACE_DLG_H 2 | #define CFIND_REPLACE_DLG_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "ui_findReplaceDialog.h" 10 | 11 | #include "Model/CFindReplaceModel.h" 12 | #include "Model/qFindReplacer/qFindReplacer.h" 13 | 14 | class CFindReplaceDlg : public QDialog, private Ui::findReplaceDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | CFindReplaceDlg(QWidget* parent, CFindReplaceModel* findReplaceModel); 20 | virtual ~CFindReplaceDlg() {}; 21 | 22 | void setFindLineEdit(QString findStr); 23 | 24 | QString getSelectedFile(); 25 | void contextMenuEvent(QContextMenuEvent* event); 26 | 27 | private slots: 28 | void on_replaceButton_clicked(); 29 | void on_cancelButton_clicked(); 30 | 31 | void on_selectAllButton_clicked(); 32 | void on_clearAllButton_clicked(); 33 | 34 | void on_fileList_itemChanged(QStandardItem *item); 35 | void on_fileEditPressed(); 36 | 37 | 38 | private: 39 | void createActions(); 40 | void showFileSelectedInStatusBar(); 41 | 42 | QStatusBar *statusbar; 43 | 44 | CFindReplaceModel* findReplaceModel_; 45 | QFindReplacer findReplacer_; 46 | }; 47 | 48 | #endif // CFIND_REPLACE_DLG_H 49 | -------------------------------------------------------------------------------- /Display/CMainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef CMAINWINDOW_H 2 | #define CMAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | // qsciscintilla 23 | #include 24 | #include 25 | 26 | 27 | 28 | #include "CEditor.h" 29 | 30 | #include "Model/CProjectManager.h" 31 | #include "Model/CProjectLoadThread.h" 32 | #include "Model/CProjectUpdateThread.h" 33 | 34 | #include "Model/CProjectListModel.h" 35 | #include "Model/CFileListModel.h" 36 | 37 | #include "Model/CFindReplaceModel.h" 38 | 39 | #include "Model/CConfigManager.h" 40 | 41 | #include "Display/CEditor.h" 42 | 43 | #include "ui_mainWindow.h" 44 | 45 | #include "CEditorFindDlg.h" 46 | 47 | #include "Utils/commonType.h" 48 | 49 | class CMainWindow : public QMainWindow, private Ui::mainWindow 50 | { 51 | Q_OBJECT 52 | 53 | public: 54 | CMainWindow(QWidget* parent = 0); 55 | virtual ~CMainWindow() {} 56 | 57 | void setSplitterSizes(const QList& splitterSizeList); 58 | void setVerticalSplitterSizes(const QList& splitterSizeList); 59 | void restoreTabWidgetPos(); 60 | 61 | QLabel* m_statusLeft; 62 | QLabel* m_statusMiddle; 63 | QLabel* m_statusRight; 64 | 65 | public slots: 66 | void loadProjectList(); 67 | void loadFileList(); 68 | void showCurrentCursorPosition(int line, int index); 69 | 70 | private slots: 71 | void on_projectAddDirectoryButton_clicked(); 72 | 73 | void on_loadProjectButton_clicked(); 74 | void on_updateProjectButton_clicked(); 75 | 76 | void projectRebuildTag(const QString projectItemName); 77 | void on_rebuildTagProjectButton_clicked(); 78 | void on_projectCopyPressed(); 79 | 80 | void on_editProjectButton_clicked(); 81 | void on_deleteProjectButton_clicked(); 82 | 83 | void on_exploreProjectButton_clicked(); 84 | void on_consoleProjectButton_clicked(); 85 | 86 | void on_aboutButton_clicked(); 87 | void on_clearOutputButton_clicked(); 88 | void on_clearLogButton_clicked(); 89 | void on_actionAlways_on_top_toggled(); 90 | void on_actionTransparent_toggled(); 91 | void on_actionToolbar_toggled(); 92 | 93 | void on_actionProject_Panel_toggled(); 94 | void on_actionFile_Panel_toggled(); 95 | 96 | void on_actionExit_triggered(); 97 | void on_actionSetting_triggered(); 98 | void on_actionFindReplaceDialog_triggered(); 99 | 100 | void setCodeBrowserFont(QsciLexer* lexer); 101 | void showInCodeBrowser(const QString &filePath, int lineNum); 102 | void codeBrowserModified(); 103 | 104 | void findText(const QString& text, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 105 | void replaceText(const QString& findText, const QString& replaceText, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 106 | void replaceAllText(const QString& findText, const QString& replaceText, bool bMatchWholeWord, bool bCaseSensitive, bool bRegularExpression); 107 | 108 | void newFile(); 109 | void openFile(); 110 | void saveFile(); 111 | void saveFileAs(); 112 | void saveFileImpl(const QString &fileName); 113 | void showFindDialog(); 114 | void showGoToDialog(); 115 | void loadFile(const QString& filePath); 116 | void setEditorFont(QsciLexer* lexer); 117 | 118 | void on_fileListItemDoubleClicked(); 119 | void on_fileEditExternalPressed(); 120 | void on_fileEditPressed(); 121 | void on_fileEditNewTabPressed(); 122 | void on_filePathCopyPressed(); 123 | void on_fileNameCopyPressed(); 124 | void on_fileCopyPressed(); 125 | void on_fileExplorePressed(); 126 | void on_fileConsolePressed(); 127 | void on_filePropertiesPressed(); 128 | 129 | void on_searchButton_clicked(); 130 | 131 | void wheelEvent(QWheelEvent *e); 132 | 133 | void updateTagBuildProgress(int percentage, QString indexingFileName); 134 | void updateCancelledTagBuild(); 135 | 136 | void updateProjectLoadProgress(int percentage); 137 | 138 | void on_errorDuringRun(const QString& cmdStr); 139 | 140 | void on_projectPatternLineEditShortcutPressed(); 141 | 142 | void on_filePatternLineEditShortcutPressed(); 143 | void on_searchLineEditShortcutPressed(); 144 | 145 | void on_infoTabWidgetToolBn_clicked(); 146 | 147 | void projectFilterRegExpChanged(); 148 | 149 | void fileFilterRegExpChanged(); 150 | 151 | void searchLineEditChanged(); 152 | 153 | void on_symbolSearchFrameShortcutPressed(); 154 | void on_nextSymbolButton_clicked(); 155 | void on_previousSymbolButton_clicked(); 156 | 157 | void on_actionFuzzyAutoComplete_toggled(); 158 | void on_actionLiveSearch_toggled(); 159 | 160 | void frameSymbolLineEditChanged(); 161 | 162 | void on_cancelTagUpdate(); 163 | 164 | void contextMenuEvent(QContextMenuEvent* event); 165 | void appendLogList(TRACE_LEVEL level, const QString& msg); 166 | void keyPressEvent(QKeyEvent *event); 167 | 168 | QString findStringCaseInsensitive(const QString& str, const QString& searchStr); 169 | void queryTag(const QString& tag); 170 | void queryTagRowLimit(const QString& tag, unsigned int limitSearchRow); 171 | void queryTagTop1000(const QString& tag); 172 | 173 | 174 | void setStatusLeft(const QString& status); 175 | void setStatusMiddle(const QString& status); 176 | void setStatusRight(const QString& status); 177 | 178 | void fileSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); 179 | 180 | void on_optionLineEdit_textChanged(const QString& text); 181 | 182 | private slots: 183 | void updateGoForwardBackwardActions(bool canGoForward, bool canGoBackward); 184 | 185 | private: 186 | void updateProjectListWidget(); 187 | void updateFileListWidget(); 188 | 189 | void setSymbolFont(QFont symbolFont); 190 | void setSymbolAutoCompleteFont(QFont symbolFont); 191 | void createActions(); 192 | 193 | QStringList getSelectedProjectItemNameList(); 194 | QStringList getSelectedFileItemNameList(); 195 | 196 | void setAlwaysOnTop(bool enable); 197 | void setTransparency(bool enable); 198 | 199 | void saveWidgetPosition(); 200 | 201 | void closeEvent(QCloseEvent *event); 202 | 203 | QProgressBar progressBar_; 204 | 205 | CProjectListModel* projectListModel_; 206 | CFileListModel* fileListModel_; 207 | 208 | CFindReplaceModel findReplaceModel_; 209 | 210 | CProjectLoadThread projectLoadThread_; 211 | CProjectUpdateThread projectUpdateThread_; 212 | 213 | QSortFilterProxyModel* projectListProxyModel_; 214 | QItemSelectionModel* projectListSelectionModel_; 215 | 216 | QTimeLine timeLine_; 217 | 218 | QShortcut* projectPatternLineEditShortcut; 219 | 220 | QShortcut* fileSearchShortcut; 221 | QShortcut* tagSearchShortcut; 222 | 223 | QShortcut* outputExploreShortcut; 224 | QShortcut* outputConsoleShortcut; 225 | QShortcut* outputPropertiesShortcut; 226 | 227 | QShortcut* projectLoadShortcut; 228 | QShortcut* projectUpdateShortcut; 229 | 230 | QShortcut* symbolSearchFrameShortcut; 231 | QShortcut* nextSymbolSearchShortcut; 232 | QShortcut* previousSymbolSearchShortcut; 233 | 234 | #ifdef Q_OS_WIN 235 | QShortcut* previousSymbolSearchShortcut_win; 236 | #endif 237 | 238 | QToolButton *pInfoTabWidgetToolBn_; 239 | 240 | bool bTagBuildInProgress_; 241 | 242 | QSize priorMainTabWidgetSize_; 243 | int infoTabWidgetWidth; 244 | 245 | CProjectItem currentProjectItem_; 246 | CProjectItem lastProjectItem_; 247 | 248 | CConfigManager* confManager_; 249 | 250 | QTagger tagger_; 251 | 252 | T_FileItemList fileItemList_; 253 | 254 | QCompleter completer_; 255 | QStringListModel stringListModel_; 256 | 257 | QTextDocument textDocument_; 258 | QPlainTextDocumentLayout* textLayout_; 259 | 260 | QMap findReplaceFileList_; // unsigned char value not used 261 | 262 | QsciScintilla codeBrowser_; 263 | CEditorFindDlg findDlg_; 264 | CEditor editor_; 265 | 266 | QString codeBrowserFileName_; 267 | 268 | }; 269 | #endif // CMAINWINDOW_H 270 | 271 | 272 | -------------------------------------------------------------------------------- /Display/CProjectDlg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "CProjectDlg.h" 8 | 9 | CProjectDlg::CProjectDlg(QWidget* parent) 10 | : QDialog(parent) 11 | { 12 | setupUi(this); 13 | 14 | currentProjectName_ = ""; 15 | } 16 | 17 | CProjectDlg::CProjectDlg(const QString& projectName, const CProjectItem& projectItem, QWidget* parent) 18 | : QDialog(parent) 19 | { 20 | setupUi(this); 21 | 22 | currentProjectName_ = projectName; 23 | 24 | projectName_lineEdit->setText(projectItem.name_); 25 | srcDir_lineEdit->setText(projectItem.srcDir_); 26 | srcFileMask_lineEdit->setText(projectItem.srcMask_); 27 | headerfileMask_lineEdit->setText(projectItem.headerMask_); 28 | labels_lineEdit->setText(projectItem.labels_); 29 | dirToExclude_lineEdit->setText(projectItem.dirToExclude_); 30 | fileMaskToExclude_lineEdit->setText(projectItem.fileMaskToExclude_); 31 | 32 | // connect slot only after when CProjectDlg has already been loaded and initial content filled in 33 | QObject::connect(projectName_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 34 | QObject::connect(srcDir_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 35 | QObject::connect(headerfileMask_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 36 | QObject::connect(srcFileMask_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 37 | QObject::connect(labels_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 38 | QObject::connect(dirToExclude_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 39 | QObject::connect(fileMaskToExclude_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(projectContentChanged())); 40 | 41 | } 42 | 43 | void CProjectDlg::on_okButton_clicked() 44 | { 45 | on_applyButton_clicked(); 46 | this->done(QDialog::Accepted); 47 | } 48 | 49 | void CProjectDlg::on_cancelButton_clicked() 50 | { 51 | this->done(QDialog::Rejected); 52 | } 53 | 54 | void CProjectDlg::on_applyButton_clicked() 55 | { 56 | CProjectItem modifiedItem; 57 | QDateTime currDateTime; 58 | 59 | // input error checking 60 | if (projectName_lineEdit->text() == "") { 61 | QMessageBox::warning(this, "Project", "Project name cannot be empty!", QMessageBox::Ok); 62 | return; 63 | } 64 | if (srcDir_lineEdit->text() == "") { 65 | QMessageBox::warning(this, "Project", "Source directory cannot be empty!", QMessageBox::Ok); 66 | return; 67 | } 68 | if ((srcFileMask_lineEdit->text() == "") && (headerfileMask_lineEdit->text() == "")) { 69 | QMessageBox::warning(this, "Project", "Source and header file mask cannot be both empty!", QMessageBox::Ok); 70 | return; 71 | } 72 | // labels can be empty so no checking 73 | 74 | modifiedItem.name_ = projectName_lineEdit->text(); 75 | modifiedItem.srcDir_ = srcDir_lineEdit->text(); 76 | modifiedItem.srcMask_ = srcFileMask_lineEdit->text(); 77 | modifiedItem.headerMask_ = headerfileMask_lineEdit->text(); 78 | modifiedItem.dirToExclude_ = dirToExclude_lineEdit->text(); 79 | modifiedItem.fileMaskToExclude_ = fileMaskToExclude_lineEdit->text(); 80 | 81 | currDateTime = QDateTime::currentDateTime(); 82 | 83 | modifiedItem.projectCreateDateTime_ = currDateTime.toString("dd/MM/yyyy hh:mm:ss"); 84 | 85 | modifiedItem.labels_ = labels_lineEdit->text(); 86 | 87 | qDebug() << "currentProjectName_ in on_applyButton_clicked() = " << currentProjectName_; 88 | 89 | CProjectItem projectItem = CProjectManager::getInstance()->getProjectItem(currentProjectName_); 90 | qDebug() << "projectItem.tagUpdateDateTime_ = " << projectItem.tagUpdateDateTime_; 91 | 92 | if (projectItem.tagUpdateDateTime_ == "") { // new project 93 | CProjectManager::getInstance()->updateProjectItem(true, modifiedItem.name_, modifiedItem); 94 | } else { // old project which has updated tag time 95 | if (currentProjectName_ == "") { // no project loaded yet 96 | CProjectManager::getInstance()->updateProjectItem(false, modifiedItem.name_, modifiedItem); 97 | } else { 98 | // use currentProjectName_ for updateProjectItem as name may have be changed 99 | CProjectManager::getInstance()->updateProjectItem(false, currentProjectName_, modifiedItem); 100 | } 101 | } 102 | 103 | setWindowModified(false); 104 | } 105 | 106 | void CProjectDlg::on_srcDir_toolBn_clicked() 107 | { 108 | QString sourceDir; 109 | 110 | if (srcDir_lineEdit->text() != "") { 111 | sourceDir = srcDir_lineEdit->text(); 112 | } else { 113 | sourceDir = QDir::currentPath(); 114 | } 115 | 116 | QString directory = QFileDialog::getExistingDirectory(this, 117 | tr("Source directory"), sourceDir); 118 | if (directory != "") { 119 | srcDir_lineEdit->setText(directory); 120 | } 121 | } 122 | 123 | void CProjectDlg::projectContentChanged() 124 | { 125 | applyButton->setEnabled(true); 126 | setWindowModified(true); 127 | } 128 | 129 | 130 | -------------------------------------------------------------------------------- /Display/CProjectDlg.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECTDLG_H 2 | #define CPROJECTDLG_H 3 | 4 | #include 5 | #include "Model/CProjectItem.h" 6 | #include "Model/CProjectManager.h" 7 | #include "ui_projectDialog.h" 8 | 9 | class CProjectDlg : public QDialog, private Ui::projectDialog 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | CProjectDlg(QWidget* parent = 0); 15 | CProjectDlg(const QString& projectName, const CProjectItem& projectItem, QWidget* parent = 0); 16 | 17 | virtual ~CProjectDlg() {} 18 | private slots: 19 | void on_okButton_clicked(); 20 | void on_cancelButton_clicked(); 21 | void on_applyButton_clicked(); 22 | void on_srcDir_toolBn_clicked(); 23 | 24 | void projectContentChanged(); 25 | private: 26 | QString currentProjectName_; 27 | }; 28 | #endif // CPROJECTDLG_H 29 | 30 | 31 | -------------------------------------------------------------------------------- /Display/CProjectListWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "CProjectListWidget.h" 2 | 3 | CProjectListWidget::CProjectListWidget(QWidget *parent) 4 | : QTreeView(parent) 5 | { 6 | QFont currentFont = static_cast (this)->font(); 7 | 8 | projectFontSize_ = currentFont.pointSize(); 9 | } 10 | 11 | void CProjectListWidget::updateProjectListWidget() 12 | { 13 | resizeColumnToContents(0); 14 | resizeColumnToContents(1); 15 | resizeColumnToContents(2); 16 | resizeColumnToContents(3); 17 | } 18 | 19 | void CProjectListWidget::mouseDoubleClickEvent(QMouseEvent* event) 20 | { 21 | emit projectItemTriggered(); 22 | QTreeView::mouseDoubleClickEvent(event); 23 | } 24 | 25 | void CProjectListWidget::keyPressEvent(QKeyEvent* event) 26 | { 27 | if (event->key() == Qt::Key_Return) { 28 | emit projectItemTriggered(); 29 | } else if ((event->key() == Qt::Key_Equal) && (event->modifiers() == Qt::ControlModifier)) { 30 | projectZoomIn(); 31 | } else if ((event->key() == Qt::Key_Minus) && (event->modifiers() == Qt::ControlModifier)) { 32 | projectZoomOut(); 33 | } 34 | 35 | QTreeView::keyPressEvent(event); 36 | } 37 | 38 | void CProjectListWidget::updateProjectFont(const QFont& projectFont) 39 | { 40 | QFont currentFont = static_cast (this)->font(); 41 | 42 | if (currentFont != projectFont) { 43 | static_cast (this)->setFont(projectFont); 44 | projectFontSize_ = projectFont.pointSize(); 45 | updateProjectListWidget(); 46 | } 47 | } 48 | 49 | void CProjectListWidget::projectZoomIn() 50 | { 51 | projectFontSize_++; 52 | QFont fnt = static_cast (this)->font();; 53 | fnt.setPointSize(projectFontSize_); 54 | static_cast (this)->setFont(fnt); 55 | 56 | updateProjectListWidget(); 57 | } 58 | 59 | void CProjectListWidget::projectZoomOut() 60 | { 61 | if (projectFontSize_ > 1) { 62 | projectFontSize_--; 63 | QFont fnt = static_cast (this)->font(); 64 | fnt.setPointSize(projectFontSize_); 65 | static_cast (this)->setFont(fnt); 66 | 67 | updateProjectListWidget(); 68 | } 69 | } 70 | 71 | void CProjectListWidget::wheelEvent(QWheelEvent *e) 72 | { 73 | /* YCH modified (begin), commented temporary */ 74 | /* 75 | if (e->modifiers() == Qt::ControlModifier) { 76 | e->accept(); 77 | if (e->delta() > 0) { 78 | projectZoomIn(); 79 | } else { 80 | projectZoomOut(); 81 | } 82 | } 83 | */ 84 | /* YCH modified (end), commented temporary */ 85 | QTreeView::wheelEvent(e); 86 | } 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /Display/CProjectListWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECT_LIST_WIDGET_H 2 | #define CPROJECT_LIST_WIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | class CProjectListWidget : public QTreeView 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | CProjectListWidget(QWidget *parent = 0); 13 | 14 | void mouseDoubleClickEvent(QMouseEvent* event); 15 | void keyPressEvent(QKeyEvent* event); 16 | 17 | void wheelEvent(QWheelEvent *e); 18 | 19 | void updateProjectFont(const QFont& projectFont); 20 | 21 | signals: 22 | void projectItemTriggered(); 23 | 24 | private: 25 | long projectFontSize_; 26 | 27 | void updateProjectListWidget(); 28 | 29 | void projectZoomIn(); 30 | void projectZoomOut(); 31 | }; 32 | 33 | #endif // CPROJECT_LIST_WIDGET_H 34 | -------------------------------------------------------------------------------- /Display/CSearchTextBrowser.cpp: -------------------------------------------------------------------------------- 1 | #include "CSearchTextBrowser.h" 2 | #include 3 | 4 | #ifdef Q_OS_WIN 5 | #include 6 | #endif 7 | 8 | CSearchTextBrowser::CSearchTextBrowser(QWidget *parent) 9 | : QTextBrowser(parent) 10 | { 11 | setLineWrapMode(QTextEdit::NoWrap); 12 | 13 | selectAllShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_A), this); 14 | connect(selectAllShortcut, SIGNAL(activated()), this, SLOT(on_selectAllPressed())); 15 | 16 | // page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); 17 | connect(this, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(on_urlClicked(const QUrl &))); 18 | 19 | confManager_ = CConfigManager::getInstance(); 20 | 21 | // default zoom level 22 | zoomIn(3); 23 | 24 | // no open links by QTextbrowser itself 25 | setOpenLinks(false); 26 | } 27 | 28 | void CSearchTextBrowser::textZoomIn() 29 | { 30 | zoomIn(1); 31 | } 32 | 33 | void CSearchTextBrowser::textZoomOut() 34 | { 35 | zoomOut(1); 36 | } 37 | 38 | bool CSearchTextBrowser::findText(const QString & subString, QTextDocument::FindFlags options) 39 | { 40 | return QTextBrowser::find(subString, options); 41 | } 42 | 43 | void CSearchTextBrowser::wheelEvent(QWheelEvent *e) 44 | { 45 | /* 46 | if (e->modifiers() == Qt::ControlModifier) { 47 | e->accept(); 48 | if (e->delta() > 0) { 49 | textZoomIn(); 50 | } else { 51 | textZoomOut(); 52 | } 53 | QTextBrowser::wheelEvent(e); 54 | } else { 55 | QTextBrowser::wheelEvent(e); 56 | } 57 | */ 58 | 59 | QTextBrowser::wheelEvent(e); 60 | } 61 | 62 | void CSearchTextBrowser::contextMenuEvent(QContextMenuEvent *event) 63 | { 64 | /* 65 | QMenu menu(this); 66 | 67 | menu.addAction(pageAction(QWebPage::SelectAll)); 68 | menu.addAction(pageAction(QWebPage::Copy)); 69 | 70 | menu.exec(event->globalPos()); 71 | */ 72 | 73 | // bypass original context menu, e.g. reload 74 | //QWebView::contextMenuEvent(event); 75 | } 76 | 77 | void CSearchTextBrowser::on_selectAllPressed() 78 | { 79 | selectAll(); 80 | } 81 | 82 | void CSearchTextBrowser::on_urlClicked(const QUrl& urlClicked) 83 | { 84 | // QMessageBox::information(this, "CSearchWebView", urlClicked.path(), QMessageBox::Ok); 85 | 86 | QString filePath = urlClicked.path(); 87 | filePath.remove(0, 1); // remove beginning "/" character 88 | 89 | filePath = "\"" + filePath + "\""; // add quote, needed for gvim handling for filename with space 90 | 91 | QString executeDir = ""; 92 | 93 | QString lineNum = urlClicked.fragment(); 94 | lineNum.remove(0, 4); // remove beginning "line" string 95 | 96 | #ifdef Q_OS_WIN 97 | QString cmdParam; 98 | 99 | QString executeMethod = "open"; 100 | QString consoleCommnad = confManager_->getAppSettingValue("DefaultEditor").toString(); 101 | 102 | if (consoleCommnad.endsWith("gvim.exe")) { 103 | cmdParam = "+" + lineNum + " " + filePath; // +lineNum fileName 104 | } else { 105 | cmdParam = filePath; // fileName 106 | } 107 | 108 | ShellExecute(NULL, reinterpret_cast(executeMethod.utf16()), reinterpret_cast(consoleCommnad.utf16()), 109 | reinterpret_cast (cmdParam.utf16()), reinterpret_cast(executeDir.utf16()), SW_NORMAL); 110 | #else 111 | // not implemented 112 | #endif 113 | } 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Display/CSearchTextBrowser.h: -------------------------------------------------------------------------------- 1 | #ifndef CSEARCH_TEXT_BROWSER_H 2 | #define CSEARCH_TEXT_BROWSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Model/CConfigManager.h" 10 | 11 | class CSearchTextBrowser : public QTextBrowser 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | CSearchTextBrowser(QWidget *parent = 0); 17 | 18 | void textZoomIn(); 19 | void textZoomOut(); 20 | 21 | bool findText(const QString & subString, QTextDocument::FindFlags options); 22 | 23 | public slots: 24 | void wheelEvent(QWheelEvent *e); 25 | void contextMenuEvent(QContextMenuEvent *event); 26 | 27 | private: 28 | QShortcut* selectAllShortcut; 29 | 30 | CConfigManager* confManager_; 31 | 32 | private slots: 33 | void on_selectAllPressed(); 34 | void on_urlClicked(const QUrl &); 35 | 36 | 37 | }; 38 | 39 | 40 | 41 | #endif // CSEARCH_TEXT_BROWSER_H 42 | 43 | -------------------------------------------------------------------------------- /Display/CSearchTextEdit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef Q_OS_WIN 16 | #include 17 | #endif 18 | 19 | #include "CSearchTextEdit.h" 20 | 21 | CSearchTextEdit::CSearchTextEdit(QWidget *parent = 0) 22 | : QPlainTextEdit(parent) 23 | { 24 | confManager_ = CConfigManager::getInstance(); 25 | setMouseTracking(true); 26 | } 27 | 28 | void CSearchTextEdit::mousePressEvent(QMouseEvent *e) 29 | { 30 | clickedAnchor = (e->button() & Qt::LeftButton) ? anchorAt(e->pos()) : 31 | QString(); 32 | 33 | if (e->button() == Qt::LeftButton) { 34 | dragStartPosition = e->pos(); 35 | } 36 | 37 | QPlainTextEdit::mousePressEvent(e); 38 | } 39 | 40 | void CSearchTextEdit::mouseMoveEvent(QMouseEvent *e) 41 | { 42 | if (!(e->buttons() & Qt::LeftButton)) { 43 | return; 44 | } 45 | if ((e->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance()) { 46 | return; 47 | } 48 | 49 | if (clickedAnchor != "") { 50 | int lineFieldPos = clickedAnchor.lastIndexOf('#'); 51 | QString sourceFileName = clickedAnchor.left(lineFieldPos); 52 | 53 | QDrag *drag = new QDrag(this); 54 | QMimeData *mimeData = new QMimeData; 55 | 56 | QList urls; 57 | QUrl url = QUrl::fromLocalFile(sourceFileName); 58 | urls.push_back(url); 59 | 60 | mimeData->setUrls(urls); 61 | drag->setMimeData(mimeData); 62 | 63 | Qt::DropAction dropAction = drag->exec(Qt::CopyAction); 64 | } 65 | 66 | QPlainTextEdit::mouseMoveEvent(e); 67 | } 68 | 69 | bool CSearchTextEdit::event(QEvent *event) 70 | { 71 | if (event->type() == QEvent::ToolTip) 72 | { 73 | QHelpEvent* helpEvent = static_cast(event); 74 | QString clickedAnchor = anchorAt(helpEvent->pos()); 75 | int lineFieldPos = clickedAnchor.lastIndexOf('#'); 76 | QString sourceFileName = clickedAnchor.left(lineFieldPos); 77 | 78 | if (clickedAnchor != "") { 79 | QToolTip::showText(helpEvent->globalPos(), sourceFileName); 80 | } else { 81 | QToolTip::hideText(); 82 | } 83 | return true; 84 | } 85 | return QPlainTextEdit::event(event); 86 | } 87 | 88 | void CSearchTextEdit::editFileExternal(const QString& sourceFileName) 89 | { 90 | qDebug() << "sourceFileName in editFileExternal() = " << sourceFileName; 91 | 92 | QFileInfo fileInfo(sourceFileName); 93 | QString executeDir = fileInfo.absoluteDir().absolutePath(); 94 | QString editFilename = ""; 95 | 96 | QString consoleCommnad = CConfigManager::getInstance()->getAppSettingValue("DefaultEditor").toString(); 97 | 98 | if (consoleCommnad == "") { 99 | QMessageBox msgBox; 100 | msgBox.setIcon(QMessageBox::Information); 101 | msgBox.setText("External editor has not be defined. Please set it in Options -> Settings -> Main -> External Editor"); 102 | msgBox.exec(); 103 | return; 104 | } 105 | 106 | #ifdef Q_OS_WIN 107 | editFilename = "\"" + sourceFileName + "\""; 108 | #else 109 | editFilename = sourceFileName; 110 | #endif 111 | 112 | #ifdef Q_OS_WIN 113 | QString excuteMethod = "open"; 114 | 115 | ShellExecute(NULL, reinterpret_cast(excuteMethod.utf16()), reinterpret_cast(consoleCommnad.utf16()), reinterpret_cast (editFilename.utf16()), reinterpret_cast(executeDir.utf16()), SW_NORMAL); 116 | #else 117 | QProcess::startDetached(consoleCommnad, QStringList(editFilename)); 118 | #endif 119 | } 120 | 121 | void CSearchTextEdit::editFile(const QString& sourceFileName, int lineNumber) 122 | { 123 | emit linkActivated(sourceFileName, lineNumber - 1); 124 | } 125 | 126 | void CSearchTextEdit::editFileNewTab(const QString& sourceFileName, int lineNumber) 127 | { 128 | emit linkActivatedNewTab(sourceFileName, lineNumber - 1); 129 | } 130 | 131 | void CSearchTextEdit::mouseReleaseEvent(QMouseEvent *e) 132 | { 133 | if (!clickedAnchor.isEmpty() && anchorAt(e->pos()) == clickedAnchor) { 134 | if (e->button() & Qt::LeftButton) { 135 | int lineFieldPos = clickedAnchor.lastIndexOf('#'); 136 | QString sourceFileName = clickedAnchor.left(lineFieldPos); 137 | int lineNumber = clickedAnchor.mid(lineFieldPos + 1, -1).toInt(); 138 | 139 | if (confManager_->getAppSettingValue("UseExternalEditor").toBool()) { 140 | editFileExternal(sourceFileName); 141 | } 142 | 143 | editFile(sourceFileName, lineNumber); 144 | } 145 | } 146 | 147 | QPlainTextEdit::mouseReleaseEvent(e); 148 | } 149 | 150 | void CSearchTextEdit::exploreDir(const QString& executeDir) 151 | { 152 | #ifdef Q_OS_WIN 153 | QString excuteMethod = "explore"; 154 | ShellExecute(NULL, reinterpret_cast(excuteMethod.utf16()), reinterpret_cast(executeDir.utf16()), NULL, NULL, SW_NORMAL); 155 | #else 156 | QDesktopServices::openUrl(QUrl(executeDir, QUrl::TolerantMode)); 157 | #endif 158 | } 159 | 160 | void CSearchTextEdit::consoleDir(const QString& executeDir) 161 | { 162 | #ifdef Q_OS_WIN 163 | QString excuteMethod = "open"; 164 | QString consoleCommnad = "cmd.exe"; 165 | 166 | ShellExecute(NULL, reinterpret_cast(excuteMethod.utf16()), reinterpret_cast(consoleCommnad.utf16()), NULL, reinterpret_cast(executeDir.utf16()), SW_NORMAL); 167 | #else 168 | QString workingDir = "--working-directory=" + executeDir; 169 | QProcess::startDetached("gnome-terminal", QStringList(workingDir)); 170 | #endif 171 | } 172 | 173 | 174 | void CSearchTextEdit::contextMenuEvent(QContextMenuEvent *event) 175 | { 176 | QMenu *menu = createStandardContextMenu(); 177 | 178 | QString clickedAnchor = anchorAt(event->pos()); 179 | 180 | if (clickedAnchor != "") { 181 | int lineFieldPos = clickedAnchor.lastIndexOf('#'); 182 | QString sourceFileName = clickedAnchor.left(lineFieldPos); 183 | int lineNumber = clickedAnchor.mid(lineFieldPos + 1, -1).toInt(); 184 | 185 | QAction actionEdit("Edit", this); 186 | QAction actionEditNewTab("Edit in New Tab", this); 187 | QAction actionEditExternal("Edit (External)", this); 188 | 189 | QAction actionExplore("Explore", this); 190 | QAction actionCopy("Copy Pathnames", this); 191 | QAction actionConsole("Console", this); 192 | 193 | QIcon iconEdit; 194 | iconEdit.addFile(QString::fromUtf8(":/Icons/22x22/edit-4.png"), QSize(), QIcon::Normal, QIcon::Off); 195 | QIcon iconExplore; 196 | iconExplore.addFile(QString::fromUtf8(":/Icons/22x22/document-open-folder.png"), QSize(), QIcon::Normal, QIcon::Off); 197 | QIcon iconCopy; 198 | iconCopy.addFile(QString::fromUtf8(":/Icons/22x22/edit-copy-4.png"), QSize(), QIcon::Normal, QIcon::Off); 199 | QIcon iconConsole; 200 | iconConsole.addFile(QString::fromUtf8(":/Icons/22x22/xconsole-2.png"), QSize(), QIcon::Normal, QIcon::Off); 201 | 202 | actionEdit.setIcon(iconEdit); 203 | actionEditNewTab.setIcon(iconEdit); 204 | 205 | actionEditExternal.setIcon(iconEdit); 206 | 207 | actionExplore.setIcon(iconExplore); 208 | actionCopy.setIcon(iconCopy); 209 | actionConsole.setIcon(iconConsole); 210 | 211 | QFileInfo fileInfo(sourceFileName); 212 | QString executeDir = fileInfo.absoluteDir().absolutePath(); 213 | 214 | connect(&actionEdit, &QAction::triggered, this, [&]{ 215 | this->editFile(sourceFileName, lineNumber); 216 | }); 217 | 218 | connect(&actionEditNewTab, &QAction::triggered, this, [&]{ 219 | this->editFileNewTab(sourceFileName, lineNumber); 220 | }); 221 | 222 | connect(&actionEditExternal, &QAction::triggered, this, [&]{ 223 | this->editFileExternal(sourceFileName); 224 | }); 225 | 226 | connect(&actionExplore, &QAction::triggered, this, [&]{ 227 | this->exploreDir(executeDir); 228 | }); 229 | 230 | connect(&actionCopy, &QAction::triggered, this, [&]{ 231 | QClipboard *clipboard = QApplication::clipboard(); 232 | clipboard->setText(sourceFileName); 233 | }); 234 | 235 | connect(&actionConsole, &QAction::triggered, this, [&]{ 236 | this->consoleDir(executeDir); 237 | }); 238 | 239 | menu->addAction(&actionEdit); 240 | menu->addAction(&actionEditNewTab); 241 | menu->addAction(&actionEditExternal); 242 | menu->addAction(&actionExplore); 243 | menu->addAction(&actionCopy); 244 | menu->addAction(&actionConsole); 245 | 246 | menu->exec(event->globalPos()); 247 | } else { 248 | menu->exec(event->globalPos()); 249 | } 250 | 251 | delete menu; 252 | } 253 | 254 | 255 | -------------------------------------------------------------------------------- /Display/CSearchTextEdit.h: -------------------------------------------------------------------------------- 1 | #ifndef CSEARCH_TEXT_EDIT_H_ 2 | #define CSEARCH_TEXT_EDIT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "Model/CConfigManager.h" 9 | 10 | class CSearchTextEdit : public QPlainTextEdit 11 | { 12 | Q_OBJECT 13 | 14 | private: 15 | QString clickedAnchor; 16 | QPoint dragStartPosition; 17 | 18 | public: 19 | CSearchTextEdit(QWidget *parent); 20 | void mousePressEvent(QMouseEvent *e); 21 | void mouseMoveEvent(QMouseEvent *e); 22 | 23 | bool event(QEvent *event); 24 | 25 | void mouseReleaseEvent(QMouseEvent *e); 26 | 27 | signals: 28 | void linkActivated(QString, int); 29 | void linkActivatedNewTab(QString, int); 30 | 31 | private: 32 | void editFile(const QString& sourceFileName, int lineNumber); 33 | void editFileNewTab(const QString& sourceFileName, int lineNumber); 34 | void editFileExternal(const QString& sourceFileName); 35 | 36 | void exploreDir(const QString& executeDir); 37 | void consoleDir(const QString& executeDir); 38 | 39 | void contextMenuEvent(QContextMenuEvent *event); 40 | 41 | CConfigManager* confManager_; 42 | 43 | }; 44 | 45 | #endif // CSEARCH_TEXT_EDIT_H_ 46 | 47 | 48 | -------------------------------------------------------------------------------- /Display/CSearchWebView.cpp: -------------------------------------------------------------------------------- 1 | #include "CSearchWebView.h" 2 | #include 3 | 4 | #ifdef Q_OS_WIN 5 | #include 6 | #endif 7 | 8 | CSearchWebView::CSearchWebView(QWidget *parent) 9 | : QWebView(parent) 10 | { 11 | selectAllShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_A), this); 12 | connect(selectAllShortcut, SIGNAL(activated()), this, SLOT(on_selectAllPressed())); 13 | 14 | page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); 15 | connect(this, SIGNAL(linkClicked(const QUrl &)), this, SLOT(on_urlClicked(const QUrl &))); 16 | 17 | confManager_ = CConfigManager::getInstance(); 18 | } 19 | 20 | void CSearchWebView::webZoomIn() 21 | { 22 | qreal currentZoomFactor = zoomFactor(); 23 | 24 | setZoomFactor(currentZoomFactor * 1.1); 25 | } 26 | 27 | void CSearchWebView::webZoomOut() 28 | { 29 | qreal currentZoomFactor = zoomFactor(); 30 | 31 | setZoomFactor(currentZoomFactor * 0.9); 32 | } 33 | 34 | bool CSearchWebView::findText(const QString & subString, QWebPage::FindFlags options) 35 | { 36 | return QWebView::findText(subString, options); 37 | } 38 | 39 | void CSearchWebView::wheelEvent(QWheelEvent *e) 40 | { 41 | if (e->modifiers() == Qt::ControlModifier) { 42 | e->accept(); 43 | if (e->delta() > 0) { 44 | webZoomIn(); 45 | } else { 46 | webZoomOut(); 47 | } 48 | QWebView::wheelEvent(e); 49 | } else { 50 | QWebView::wheelEvent(e); 51 | } 52 | } 53 | 54 | void CSearchWebView::contextMenuEvent(QContextMenuEvent *event) 55 | { 56 | QMenu menu(this); 57 | 58 | menu.addAction(pageAction(QWebPage::SelectAll)); 59 | menu.addAction(pageAction(QWebPage::Copy)); 60 | menu.exec(event->globalPos()); 61 | 62 | // bypass original context menu, e.g. reload 63 | //QWebView::contextMenuEvent(event); 64 | } 65 | 66 | void CSearchWebView::on_selectAllPressed() 67 | { 68 | this->triggerPageAction(QWebPage::SelectAll); 69 | } 70 | 71 | void CSearchWebView::on_urlClicked(const QUrl& urlClicked) 72 | { 73 | // QMessageBox::information(this, "CSearchWebView", urlClicked.path(), QMessageBox::Ok); 74 | 75 | QString filePath = urlClicked.path(); 76 | filePath.remove(0, 1); // remove beginning "/" character 77 | 78 | QString executeDir = ""; 79 | 80 | QString lineNum = urlClicked.fragment(); 81 | lineNum.remove(0, 4); // remove beginning "line" string 82 | 83 | #ifdef Q_OS_WIN 84 | QString cmdParam; 85 | 86 | QString executeMethod = "open"; 87 | QString consoleCommnad = confManager_->getAppSettingValue("DefaultEditor").toString(); 88 | 89 | if (consoleCommnad.endsWith("gvim.exe")) { 90 | cmdParam = "+" + lineNum + " " + filePath; // +lineNum fileName 91 | } else { 92 | cmdParam = filePath; // fileName 93 | } 94 | 95 | ShellExecute(NULL, reinterpret_cast(executeMethod.utf16()), reinterpret_cast(consoleCommnad.utf16()), 96 | reinterpret_cast (cmdParam.utf16()), reinterpret_cast(executeDir.utf16()), SW_NORMAL); 97 | #else 98 | // not implemented 99 | #endif 100 | } 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Display/CSearchWebView.h: -------------------------------------------------------------------------------- 1 | #ifndef CSEARCH_WEB_VIEW_H 2 | #define CSEARCH_WEB_VIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "Model/CConfigManager.h" 12 | 13 | class CSearchWebView : public QWebView 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | CSearchWebView(QWidget *parent = 0); 19 | 20 | void webZoomIn(); 21 | void webZoomOut(); 22 | 23 | bool findText(const QString & subString, QWebPage::FindFlags options); 24 | 25 | public slots: 26 | void wheelEvent(QWheelEvent *e); 27 | void contextMenuEvent(QContextMenuEvent *event); 28 | 29 | private: 30 | QShortcut* selectAllShortcut; 31 | 32 | CConfigManager* confManager_; 33 | 34 | private slots: 35 | void on_selectAllPressed(); 36 | void on_urlClicked(const QUrl &); 37 | 38 | 39 | }; 40 | 41 | 42 | 43 | #endif // CSEARCH_WEB_VIEW_H 44 | 45 | -------------------------------------------------------------------------------- /Model/CConfigManager.cpp: -------------------------------------------------------------------------------- 1 | #include "CConfigManager.h" 2 | 3 | CConfigManager* CConfigManager::manager_ = 0; 4 | 5 | CConfigManager* CConfigManager::getInstance() 6 | { 7 | if (manager_ == 0) { 8 | manager_ = new CConfigManager(); 9 | } 10 | return manager_; 11 | } 12 | 13 | CConfigManager::CConfigManager() 14 | { 15 | confSetting = new QSettings(QSettings::IniFormat, QSettings::UserScope, 16 | "blink", "blink"); 17 | } 18 | 19 | QVariant CConfigManager::getAppSettingValue(const QString& key) const 20 | { 21 | if (key == "TagDir") { // default directory for storing tags 22 | return confSetting->value("Setting/" + key, "tags"); 23 | } else{ 24 | return confSetting->value("Setting/" + key); 25 | } 26 | } 27 | 28 | QVariant CConfigManager::getAppSettingValue(const QString& key, const QVariant &defaultValue) const 29 | { 30 | if (key == "TagDir") { // default directory for storing tags 31 | return confSetting->value("Setting/" + key, "tags"); 32 | } else { 33 | return confSetting->value("Setting/" + key, defaultValue); 34 | } 35 | } 36 | 37 | void CConfigManager::setAppSettingValue(const QString& key, const QVariant& val) 38 | { 39 | confSetting->setValue("Setting/" + key, val); 40 | } 41 | 42 | QVariant CConfigManager::getValue(const QString& section, const QString& key) const 43 | { 44 | return confSetting->value(section + "/" + key); 45 | } 46 | 47 | QVariant CConfigManager::getValue(const QString& section, const QString& key, const QVariant &defaultValue) const 48 | { 49 | return confSetting->value(section + "/" + key, defaultValue); 50 | } 51 | 52 | void CConfigManager::setValue(const QString& section, const QString& key, const QVariant& val) 53 | { 54 | confSetting->setValue(section + "/" + key, val); 55 | } 56 | 57 | void CConfigManager::updateConfig() 58 | { 59 | confSetting->sync(); 60 | } 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Model/CConfigManager.h: -------------------------------------------------------------------------------- 1 | #ifndef CCONFIG_MANAGER_H 2 | #define CCONFIG_MANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class CConfigManager: public QObject 9 | { 10 | Q_OBJECT 11 | public: 12 | CConfigManager(); 13 | 14 | virtual ~CConfigManager() {}; 15 | 16 | static CConfigManager* getInstance(); 17 | 18 | QVariant getAppSettingValue(const QString& key) const; 19 | QVariant getAppSettingValue(const QString& key, const QVariant &defaultValue) const; 20 | 21 | void setAppSettingValue(const QString& key, const QVariant& val); 22 | 23 | QVariant getValue(const QString& section, const QString& key) const; 24 | QVariant getValue(const QString& section, const QString& key, const QVariant &defaultValue) const; 25 | 26 | void setValue(const QString& section, const QString& key, const QVariant& val); 27 | 28 | void updateConfig(); 29 | 30 | private: 31 | static CConfigManager* manager_; 32 | QSettings* confSetting; 33 | }; 34 | 35 | 36 | #endif // CCONFIG_MANAGER_H 37 | -------------------------------------------------------------------------------- /Model/CFileItem.cpp: -------------------------------------------------------------------------------- 1 | #include "CFileItem.h" 2 | 3 | CFileItem::CFileItem() 4 | { 5 | fileId_ = 0; 6 | fileName_ = ""; 7 | fileLastModified_ = ""; 8 | fileSize_ = 0; 9 | } 10 | 11 | CFileItem::CFileItem(long fileId, const QString& fileName, const QString& fileLastModified, qint64 fileSize) 12 | { 13 | fileId_ = fileId; 14 | 15 | fileName_ = fileName; 16 | fileLastModified_ = fileLastModified; 17 | 18 | fileSize_ = fileSize; 19 | } 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Model/CFileItem.h: -------------------------------------------------------------------------------- 1 | #ifndef CFILE_ITEM_H 2 | #define CFILE_ITEM_H 3 | 4 | #include 5 | #include 6 | 7 | class CFileItem 8 | { 9 | public: 10 | 11 | CFileItem(); 12 | CFileItem(long fileId, const QString& fileName, const QString& fileLastModified, qint64 fileSize); 13 | 14 | virtual ~CFileItem() {}; 15 | 16 | long fileId_; 17 | QString fileName_; 18 | QString fileLastModified_; 19 | 20 | qint64 fileSize_; 21 | }; 22 | 23 | #endif // CFILE_ITEM_H 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Model/CFileListModel.cpp: -------------------------------------------------------------------------------- 1 | #include "CFileListModel.h" 2 | 3 | CFileListModel::CFileListModel(QObject *parent) 4 | : QStandardItemModel(0, 3, parent) // 3 column 5 | { 6 | parent_ = static_cast (parent); 7 | setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); 8 | setHeaderData(1, Qt::Horizontal, QObject::tr("Last Modified")); 9 | setHeaderData(2, Qt::Horizontal, QObject::tr("Size")); 10 | 11 | fileListProxyModel_ = new QSortFilterProxyModel; 12 | fileListProxyModel_->setSourceModel(static_cast (this)); 13 | fileListProxyModel_->setDynamicSortFilter(true); 14 | 15 | fileListSelectionModel_ = new QItemSelectionModel(fileListProxyModel_); 16 | 17 | qDebug() << "CFileListModel, this = " << this; 18 | } 19 | 20 | void CFileListModel::clearAndResetModel() 21 | { 22 | clear(); // header data will also be clear 23 | 24 | setColumnCount(3); // need to set back column count when QStandardItemModel clear otherwise setData will return false 25 | 26 | setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); 27 | setHeaderData(1, Qt::Horizontal, QObject::tr("Last Modified")); 28 | setHeaderData(2, Qt::Horizontal, QObject::tr("Size")); 29 | } 30 | 31 | QSortFilterProxyModel* CFileListModel::getProxyModel() 32 | { 33 | return fileListProxyModel_; 34 | } 35 | 36 | QItemSelectionModel* CFileListModel::getSelectionModel() 37 | { 38 | return fileListSelectionModel_; 39 | } 40 | 41 | void CFileListModel::addItem(const CFileItem& fileItem) 42 | { 43 | quint64 fileSize; 44 | QDateTime lastModifiedDateTime; 45 | 46 | insertRow(0); 47 | 48 | setData(index(0, 0), fileItem.fileName_); 49 | 50 | setData(index(0, 0), QIcon(":/Icons/text-x-preview.ico"), Qt::DecorationRole); 51 | 52 | lastModifiedDateTime = QDateTime::fromString(fileItem.fileLastModified_, "dd/MM/yyyy HH:mm:ss"); 53 | setData(index(0, 1), lastModifiedDateTime); 54 | 55 | fileSize = fileItem.fileSize_; 56 | 57 | setData(index(0, 2), fileSize); 58 | } 59 | 60 | QVariant CFileListModel::data(const QModelIndex& index, int role) const 61 | { 62 | return QStandardItemModel::data(index,role); 63 | } 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Model/CFileListModel.h: -------------------------------------------------------------------------------- 1 | #ifndef CFILE_LIST_MODEL_H 2 | #define CFILE_LIST_MODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "Model/CFileItem.h" 17 | 18 | class CFileListModel: public QStandardItemModel 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | CFileListModel(QObject *parent = 0); 24 | void clearAndResetModel(); 25 | 26 | QSortFilterProxyModel* getProxyModel(); 27 | QItemSelectionModel* getSelectionModel(); 28 | 29 | void addItem(const CFileItem& fileItem); 30 | 31 | QVariant data(const QModelIndex& index, int role) const; 32 | 33 | private: 34 | QWidget* parent_; 35 | 36 | QSortFilterProxyModel* fileListProxyModel_; 37 | QItemSelectionModel* fileListSelectionModel_; 38 | 39 | }; 40 | 41 | #endif // CFILE_LIST_MODEL_H 42 | -------------------------------------------------------------------------------- /Model/CFindReplaceModel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include "CFindReplaceModel.h" 7 | 8 | CFindReplaceModel::CFindReplaceModel() 9 | { 10 | fileListModel_ = new QStandardItemModel(); 11 | } 12 | 13 | CFindReplaceModel::~CFindReplaceModel() 14 | { 15 | delete fileListModel_; 16 | } 17 | 18 | // fileList passed by value instead of reference as caller may use local variables in stack 19 | void CFindReplaceModel::setFileList(QStringList fileList) 20 | { 21 | fileList_ = fileList; 22 | 23 | fileListModel_->clear(); 24 | 25 | foreach (const QString &filePath, fileList) { 26 | QStandardItem* item = new QStandardItem(filePath); 27 | item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); 28 | item->setData(QVariant(Qt::Checked), Qt::CheckStateRole); 29 | fileListModel_->appendRow(item); 30 | } 31 | } 32 | 33 | QStringList CFindReplaceModel::getFileList() 34 | { 35 | QModelIndex parent; 36 | int i; 37 | QStringList selectedFileList; 38 | 39 | for (i = 0; i < fileListModel_->rowCount(parent); i++) { 40 | QStandardItem* item = fileListModel_->item(i, 0); // always column 0 41 | if (item->checkState() == Qt::Checked) { 42 | selectedFileList.append(item->text()); 43 | } 44 | } 45 | 46 | return selectedFileList; 47 | } 48 | 49 | QStringList CFindReplaceModel::selectAllFiles() 50 | { 51 | QModelIndex parent; 52 | int i; 53 | QStringList selectedFileList; 54 | 55 | for (i = 0; i < fileListModel_->rowCount(parent); i++) { 56 | QStandardItem* item = fileListModel_->item(i, 0); // always column 0 57 | item->setCheckState(Qt::Checked); 58 | } 59 | 60 | return selectedFileList; 61 | } 62 | 63 | QStringList CFindReplaceModel::clearSelectAllFiles() 64 | { 65 | QModelIndex parent; 66 | int i; 67 | QStringList selectedFileList; 68 | 69 | for (i = 0; i < fileListModel_->rowCount(parent); i++) { 70 | QStandardItem* item = fileListModel_->item(i, 0); // always column 0 71 | item->setCheckState(Qt::Unchecked); 72 | } 73 | 74 | return selectedFileList; 75 | } 76 | 77 | QStandardItemModel* CFindReplaceModel::getFileListModel() { 78 | return fileListModel_; 79 | } 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Model/CFindReplaceModel.h: -------------------------------------------------------------------------------- 1 | #ifndef CFIND_REPLACE_MODEL_H 2 | #define CFIND_REPLACE_MODEL_H 3 | 4 | #include 5 | 6 | class CFindReplaceModel 7 | { 8 | public: 9 | CFindReplaceModel(); 10 | virtual ~CFindReplaceModel(); 11 | 12 | void setFileList(QStringList fileList); 13 | QStringList getFileList() ; 14 | 15 | QStringList selectAllFiles(); 16 | QStringList clearSelectAllFiles(); 17 | 18 | QStandardItemModel* getFileListModel(); 19 | 20 | private: 21 | QStandardItemModel* fileListModel_; 22 | 23 | QStringList fileList_; 24 | }; 25 | 26 | 27 | #endif // CFIND_REPLACE_MODEL_H 28 | 29 | -------------------------------------------------------------------------------- /Model/CProjectItem.cpp: -------------------------------------------------------------------------------- 1 | #include "CProjectItem.h" 2 | 3 | CProjectItem::CProjectItem() 4 | { 5 | name_ = ""; 6 | srcDir_ = ""; 7 | srcMask_ = ""; 8 | headerMask_ = ""; 9 | tagUpdateDateTime_ = ""; 10 | projectCreateDateTime_ = ""; 11 | labels_ = ""; 12 | dirToExclude_ = ""; 13 | fileMaskToExclude_ = ""; 14 | } 15 | 16 | CProjectItem::CProjectItem(const QString& name, const QString& srcDir, const QString& srcMask, const QString& headerMask, 17 | const QString& tagUpdateDateTime, const QString& projectCreateDateTime, const QString& labels, 18 | const QString& dirToExclude, const QString& fileMaskToExclude) 19 | { 20 | name_ = name; 21 | srcDir_ = srcDir; 22 | srcMask_ = srcMask; 23 | headerMask_ = headerMask; 24 | 25 | tagUpdateDateTime_ = tagUpdateDateTime; 26 | projectCreateDateTime_ = projectCreateDateTime; 27 | labels_ = labels; 28 | dirToExclude_ = dirToExclude; 29 | fileMaskToExclude_ = fileMaskToExclude; 30 | } 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Model/CProjectItem.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECT_ITEM_H 2 | #define CPROJECT_ITEM_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class CProjectItem 9 | { 10 | public: 11 | 12 | CProjectItem(); 13 | 14 | CProjectItem(const QString& name, const QString& srcDir, const QString& srcMask, const QString& headerMask, 15 | const QString& tagUpdateDateTime, const QString& projectCreateDateTime, const QString& labels, 16 | const QString& dirToExclude, const QString& fileMaskToExclude); 17 | 18 | QString name_, 19 | srcDir_, 20 | srcMask_, 21 | headerMask_, 22 | 23 | tagUpdateDateTime_, 24 | projectCreateDateTime_, 25 | 26 | labels_, 27 | dirToExclude_, 28 | fileMaskToExclude_; 29 | 30 | virtual ~CProjectItem() {}; 31 | }; 32 | 33 | #endif // CPROJECT_ITEM_H 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Model/CProjectListModel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "CProjectListModel.h" 8 | #include "Display/CProjectDlg.h" 9 | 10 | CProjectListModel::CProjectListModel(QObject *parent) 11 | : QStandardItemModel(0, 4, parent) 12 | { 13 | parent_ = static_cast (parent); 14 | confManager_ = CConfigManager::getInstance(); 15 | 16 | // view when list is empty, view with content in CMainWindow::loadProjectList() 17 | setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); 18 | setHeaderData(1, Qt::Horizontal, QObject::tr("Tag Update Datatime")); 19 | setHeaderData(2, Qt::Horizontal, QObject::tr("Project Create Datetime")); 20 | setHeaderData(3, Qt::Horizontal, QObject::tr("Labels")); 21 | } 22 | 23 | void CProjectListModel::addProjectItem(const CProjectItem& projectItem) 24 | { 25 | QDateTime tagUpdateDateTime, projectCreateDatetime; 26 | 27 | insertRow(0); 28 | 29 | setData(index(0, 0), projectItem.name_); 30 | 31 | if (projectItem.tagUpdateDateTime_ == "") { 32 | setData(index(0, 1), ""); 33 | } else { 34 | tagUpdateDateTime = QDateTime::fromString(projectItem.tagUpdateDateTime_, "dd/MM/yyyy HH:mm:ss"); 35 | setData(index(0, 1), tagUpdateDateTime); 36 | } 37 | 38 | if (projectItem.projectCreateDateTime_ == "") { 39 | setData(index(0, 2), ""); 40 | } else { 41 | projectCreateDatetime = QDateTime::fromString(projectItem.projectCreateDateTime_, "dd/MM/yyyy HH:mm:ss"); 42 | setData(index(0, 2), projectCreateDatetime); 43 | } 44 | 45 | setData(index(0, 3), projectItem.labels_); 46 | 47 | } 48 | 49 | bool CProjectListModel::dropMimeData(const QMimeData *data, Qt::DropAction action, 50 | int row, int column, const QModelIndex &parent) 51 | { 52 | QList urlList; 53 | 54 | QFileInfo info; 55 | QString fName; 56 | 57 | CProjectItem droppedItem; 58 | 59 | urlList = data->urls(); // retrieve list of urls 60 | 61 | foreach(QUrl url, urlList) // iterate over list 62 | { 63 | //qDebug("url = %s", url.toString().toLatin1().constData()); 64 | fName = url.toLocalFile(); 65 | //qDebug("fName = %s", fName.toLatin1().constData()); 66 | info.setFile(fName); 67 | 68 | if (info.isDir()) { 69 | 70 | // fill default value according to item dropped 71 | droppedItem.name_ = info.fileName(); 72 | droppedItem.srcDir_ = fName; 73 | 74 | QString defaultMaskForNewProject = confManager_->getAppSettingValue("defaultMaskForNewProject").toString(); 75 | 76 | if (defaultMaskForNewProject == "") { 77 | droppedItem.srcMask_ = "*"; 78 | } else { 79 | droppedItem.srcMask_ = defaultMaskForNewProject; 80 | } 81 | 82 | QString defaultDirToExclude = confManager_->getAppSettingValue("defaultDirToExclude").toString(); 83 | if (defaultDirToExclude == "") { 84 | droppedItem.dirToExclude_ = ".git"; 85 | } else { 86 | droppedItem.dirToExclude_ = defaultDirToExclude; 87 | } 88 | 89 | QString defaultFileMaskToExclude = confManager_->getAppSettingValue("defaultFileMaskToExclude").toString(); 90 | if (defaultFileMaskToExclude == "") { 91 | droppedItem.fileMaskToExclude_ = "*.tmp"; 92 | } else { 93 | droppedItem.fileMaskToExclude_ = defaultFileMaskToExclude; 94 | } 95 | 96 | droppedItem.headerMask_ = ""; 97 | droppedItem.labels_ = ""; 98 | 99 | QDialog* dialog = new CProjectDlg(droppedItem.name_, droppedItem, parent_); 100 | dialog->exec(); 101 | } else { 102 | QMessageBox::information(parent_, "Add project", "Only folder is supported!", QMessageBox::Ok); 103 | } 104 | } 105 | return true; 106 | } 107 | 108 | QStringList CProjectListModel::mimeTypes () const 109 | { 110 | QStringList qstrList; 111 | // list of accepted mime types accepted 112 | qstrList.append("text/uri-list"); 113 | return qstrList; 114 | } 115 | 116 | Qt::DropActions CProjectListModel::supportedDropActions () const 117 | { 118 | // actions supported 119 | return Qt::CopyAction | Qt::MoveAction; 120 | } 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Model/CProjectListModel.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECT_LIST_MODEL_H 2 | #define CPROJECT_LIST_MODEL_H 3 | 4 | #include 5 | #include "Model/CProjectItem.h" 6 | #include "Model/CConfigManager.h" 7 | 8 | class CProjectListModel: public QStandardItemModel 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | CProjectListModel(QObject *parent = 0); 14 | 15 | void addProjectItem(const CProjectItem& projectItem); 16 | 17 | bool dropMimeData(const QMimeData *data, Qt::DropAction action, 18 | int row, int column, const QModelIndex &parent); 19 | QStringList mimeTypes() const; 20 | 21 | Qt::DropActions supportedDropActions() const; 22 | 23 | QWidget* parent_; 24 | CConfigManager* confManager_; 25 | }; 26 | 27 | #endif // CPROJECT_LIST_MODEL_H 28 | -------------------------------------------------------------------------------- /Model/CProjectLoadThread.cpp: -------------------------------------------------------------------------------- 1 | #include "CProjectLoadThread.h" 2 | 3 | CProjectLoadThread::CProjectLoadThread(QObject *parent) 4 | : QThread(parent) 5 | { 6 | taggerPtr_ = NULL; 7 | fileItemListPtr_ = NULL; 8 | } 9 | 10 | void CProjectLoadThread::setTaggerPtr(QTagger* taggerPtr) 11 | { 12 | taggerPtr_ = taggerPtr; 13 | } 14 | 15 | void CProjectLoadThread::setFileItemListPtr(T_FileItemList* fileItemListPtr) 16 | { 17 | fileItemListPtr_ = fileItemListPtr; 18 | } 19 | 20 | void CProjectLoadThread::setCurrentProjectItem(const CProjectItem& projectItem) 21 | { 22 | projectItem_ = projectItem; 23 | } 24 | 25 | CProjectItem CProjectLoadThread::getCurrentProjectItem() 26 | { 27 | return projectItem_; 28 | } 29 | 30 | 31 | bool CProjectLoadThread::runCommand(const QString& program, const QString& workDir, const QString& redirectFile) 32 | { 33 | QString errStr; 34 | CRunCommand::ENUM_RunCommandErr cmdErr; 35 | 36 | cmdErr = (CRunCommand::ENUM_RunCommandErr) cmd_.startRun(program, workDir, redirectFile, errStr); 37 | 38 | switch (cmdErr) { 39 | case CRunCommand::E_RUNCMD_NO_ERROR: 40 | break; 41 | case CRunCommand::E_RUNCMD_CANCELLED: 42 | return false; 43 | break; 44 | case CRunCommand::E_RUNCMD_FAILSTART: 45 | return false; 46 | break; 47 | case CRunCommand::E_RUNCMD_ERRRUN: 48 | return false; 49 | break; 50 | case CRunCommand::E_RUNCMD_CRASHED: 51 | return false; 52 | break; 53 | default: 54 | break; 55 | } 56 | 57 | return true; 58 | } 59 | 60 | void CProjectLoadThread::run() 61 | { 62 | QDir currentDir(QDir::currentPath()); 63 | 64 | // using absolutePath so relative and absolute path also possible 65 | QString tagDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tags/" + projectItem_.name_; 66 | 67 | // write output to qtag config file 68 | QFile qTagConfigFile(QTagger::kQTAG_CONFIG_FILE); 69 | 70 | qTagConfigFile.open(QIODevice::WriteOnly | QIODevice::Text); 71 | QTextStream qTagConfigFileOut(&qTagConfigFile); 72 | qTagConfigFileOut << "projectLoad=" << projectItem_.name_ << Qt::endl; 73 | 74 | qTagConfigFile.close(); 75 | 76 | QString tagDbFileName = tagDir + "/" + QString(QTagger::kQTAG_DEFAULT_TAGDBNAME); 77 | 78 | if (taggerPtr_ != NULL) { 79 | qDebug() << "loadTagList() for " << tagDbFileName << " IN"; 80 | taggerPtr_->loadTagList(tagDbFileName); 81 | qDebug() << "loadTagList() for " << tagDbFileName << " OUT"; 82 | } 83 | 84 | QString outputFile; 85 | int bListFileOpenResult = -1; 86 | 87 | outputFile = tagDir + "/" + QTagger::kQTAG_DEFAULT_INPUTLIST_FILE; 88 | 89 | if (fileItemListPtr_ != NULL) { 90 | fileItemListPtr_->clear(); 91 | qDebug() << "loadFileList() for " << outputFile << " IN"; 92 | bListFileOpenResult = CSourceFileList::loadFileList(outputFile, *fileItemListPtr_); 93 | qDebug() << "loadFileList() for " << outputFile << " OUT"; 94 | } 95 | 96 | qDebug() << "outputFile = " << outputFile << Qt::endl; 97 | 98 | if (bListFileOpenResult == 0) { 99 | emit projectLoadPercentageCompleted(100); 100 | } else { 101 | emit projectLoadPercentageCompleted(0); 102 | } 103 | } 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /Model/CProjectLoadThread.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECT_LOAD_THREAD_H 2 | #define CPROJECT_LOAD_THREAD_H 3 | 4 | #include 5 | #include 6 | 7 | #include "Model/qTagger/qTagger.h" 8 | 9 | #include "Model/CProjectItem.h" 10 | #include "Model/CRunCommand.h" 11 | #include "Model/CConfigManager.h" 12 | 13 | class CProjectLoadThread: public QThread 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | CProjectLoadThread(QObject *parent = 0); 19 | 20 | void setCurrentProjectItem(const CProjectItem& projectItem); 21 | 22 | void setFileItemListPtr(T_FileItemList* fileItemListPtr); 23 | void setTaggerPtr(QTagger* taggerPtrPtr); 24 | 25 | CProjectItem getCurrentProjectItem(); 26 | 27 | void run(); 28 | 29 | signals: 30 | void projectLoadPercentageCompleted(int percentage); 31 | 32 | private: 33 | bool runCommand(const QString& program, const QString& workDir, const QString& redirectFile = ""); 34 | CProjectItem projectItem_; 35 | 36 | CRunCommand cmd_; 37 | QTagger* taggerPtr_; 38 | 39 | T_FileItemList* fileItemListPtr_; 40 | 41 | }; 42 | 43 | #endif // CPROJECT_LOAD_THREAD_H 44 | -------------------------------------------------------------------------------- /Model/CProjectManager.cpp: -------------------------------------------------------------------------------- 1 | #include "CProjectManager.h" 2 | #include "CConfigManager.h" 3 | 4 | #include "Utils/CUtils.h" 5 | 6 | CProjectManager* CProjectManager::manager_ = 0; 7 | 8 | CProjectManager::CProjectManager() 9 | { 10 | 11 | } 12 | 13 | CProjectManager* CProjectManager::getInstance() 14 | { 15 | if (manager_ == 0) { 16 | manager_ = new CProjectManager(); 17 | } 18 | return manager_; 19 | } 20 | 21 | void CProjectManager::setProjectFile(const QString& projectFileName) 22 | { 23 | projectFile_ = projectFileName; 24 | } 25 | 26 | void CProjectManager::setStorageHandler(const CXmlStorageHandler& handler) 27 | { 28 | handler_ = handler; 29 | } 30 | 31 | void CProjectManager::attachStorage() 32 | { 33 | handler_.loadFromFile(projectFile_, projectMap_); 34 | } 35 | 36 | void CProjectManager::flushStorage() 37 | { 38 | handler_.saveToFile(projectFile_, projectMap_); 39 | } 40 | 41 | void CProjectManager::detachStorage() 42 | { 43 | handler_.saveToFile(projectFile_, projectMap_); 44 | } 45 | 46 | void CProjectManager::getProjectMap(QMap& projectMap) 47 | { 48 | projectMap = projectMap_; 49 | } 50 | 51 | CProjectItem CProjectManager::getProjectItem(const QString& projectItemName) const 52 | { 53 | // qDebug() << "getItem" << projectItemName << "called!\n"; 54 | // qDebug() << "projectMap_[projectItemName].name_ = " << projectMap_[projectItemName].name_ << Qt::endl; 55 | // qDebug() << "projectMap_[projectItemName].srcDir_ = " << projectMap_[projectItemName].srcDir_ << Qt::endl; 56 | return projectMap_[projectItemName]; 57 | } 58 | 59 | void CProjectManager::addItem(const CProjectItem& newItem) 60 | { 61 | projectMap_[newItem.name_] = newItem; 62 | emit projectMapUpdated(); 63 | flushStorage(); 64 | } 65 | 66 | void CProjectManager::updateProjectItem(bool newProject, const QString& projectItemName, const CProjectItem& newItem) 67 | { 68 | QString tagDir; 69 | 70 | // current directory 71 | QDir currentDir(QDir::currentPath()); 72 | 73 | if (projectItemName != newItem.name_) { // project renamed 74 | qDebug() << "newItem.name_ = " << newItem.name_; 75 | qDebug() << "projectItemName = " << projectItemName; 76 | 77 | projectMap_.remove(projectItemName); // remove old one 78 | 79 | // using absoluteFilePath so relative and absolute path also possible 80 | tagDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tags/" + projectItemName; 81 | QDir dir(tagDir); 82 | 83 | // remove tag directory 84 | CUtils::removeDirectory(dir); 85 | } 86 | 87 | projectMap_[newItem.name_] = newItem; 88 | emit projectMapUpdated(); 89 | flushStorage(); 90 | 91 | if (newProject) { 92 | emit newProjectAdded(projectItemName); 93 | } 94 | } 95 | 96 | void CProjectManager::removeProjectItem(const QString& projectItemName) 97 | { 98 | QString tagDir; 99 | 100 | // current directory 101 | QDir currentDir(QDir::currentPath()); 102 | 103 | // using absoluteFilePath so relative and absolute path also possible 104 | tagDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tags/" + projectItemName; 105 | QDir dir(tagDir); 106 | 107 | // remove tag directory 108 | CUtils::removeDirectory(dir); 109 | 110 | // remove from map 111 | projectMap_.remove(projectItemName); 112 | emit projectMapUpdated(); 113 | flushStorage(); 114 | 115 | } 116 | 117 | void CProjectManager::destroy() 118 | { 119 | delete manager_; 120 | } 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Model/CProjectManager.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECT_MANAGER_H 2 | #define CPROJECT_MANAGER_H 3 | 4 | #include "Model/CProjectItem.h" 5 | #include "Storage/IStorageHandler.h" 6 | #include "Storage/CXmlStorageHandler.h" 7 | 8 | class CProjectManager: public QObject 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | virtual ~CProjectManager() {}; 14 | 15 | static CProjectManager* getInstance(); 16 | 17 | void setProjectFile(const QString& projectFileName); 18 | void setStorageHandler(const CXmlStorageHandler& handler); 19 | void attachStorage(); 20 | void flushStorage(); 21 | void detachStorage(); 22 | 23 | void getProjectMap(QMap& projectMap); 24 | 25 | void addItem(const CProjectItem& newItem); 26 | 27 | CProjectItem getProjectItem(const QString& projectItemName) const; 28 | 29 | void updateProjectItem(bool newProject, const QString& projectItemName, const CProjectItem& newItem); 30 | 31 | void removeProjectItem(const QString& projectItemName); 32 | 33 | void destroy(); 34 | 35 | protected: 36 | CProjectManager(); 37 | 38 | signals: 39 | void projectMapUpdated(); 40 | void newProjectAdded(QString projectItemName); 41 | 42 | private: 43 | CXmlStorageHandler handler_; 44 | 45 | QMap projectMap_; 46 | 47 | QString projectFile_; 48 | 49 | static CProjectManager* manager_; 50 | 51 | }; 52 | 53 | #endif // CPROJECT_MANAGER_H 54 | 55 | 56 | -------------------------------------------------------------------------------- /Model/CProjectUpdateThread.cpp: -------------------------------------------------------------------------------- 1 | #include "CProjectUpdateThread.h" 2 | 3 | CProjectUpdateThread::CProjectUpdateThread(QObject *parent) 4 | : QThread(parent), 5 | bCancelUpdate_(false) 6 | { 7 | 8 | } 9 | 10 | void CProjectUpdateThread::setCurrentProjectItem(const CProjectItem& projectItem) 11 | { 12 | projectItem_ = projectItem; 13 | } 14 | 15 | void CProjectUpdateThread::setRebuildTag(bool bRebuildTag) 16 | { 17 | bRebuildTag_ = bRebuildTag; 18 | } 19 | 20 | void CProjectUpdateThread::initStep(int totalStep) 21 | { 22 | stepCompleted_ = 0; 23 | totalStep_ = totalStep; 24 | 25 | emit percentageCompleted(0, ""); // emit 0 initially 26 | } 27 | 28 | void CProjectUpdateThread::finishOneStep(const QString& indexingFileName) 29 | { 30 | int endPercent; 31 | stepCompleted_++; 32 | endPercent = stepCompleted_ * (100 / totalStep_); 33 | emit percentageCompleted(endPercent, indexingFileName); 34 | 35 | if (stepCompleted_ >= totalStep_) { 36 | emit percentageCompleted(100, ""); // always 100% if finish all steps 37 | } 38 | } 39 | 40 | void CProjectUpdateThread::finishAllStep() 41 | { 42 | emit percentageCompleted(100, ""); 43 | } 44 | 45 | bool CProjectUpdateThread::runCommand(const QString& program, const QString& workDir, const QString& redirectFile) 46 | { 47 | QString errStr; 48 | CRunCommand::ENUM_RunCommandErr cmdErr; 49 | 50 | cmdErr = (CRunCommand::ENUM_RunCommandErr) cmd_.startRun(program, workDir, redirectFile, errStr); 51 | 52 | switch (cmdErr) { 53 | case CRunCommand::E_RUNCMD_NO_ERROR: 54 | break; 55 | case CRunCommand::E_RUNCMD_CANCELLED: 56 | emit cancelledTagBuild(); 57 | return false; 58 | break; 59 | case CRunCommand::E_RUNCMD_FAILSTART: 60 | emit errorDuringRun(errStr); 61 | return false; 62 | break; 63 | case CRunCommand::E_RUNCMD_ERRRUN: 64 | emit errorDuringRun(errStr); 65 | return false; 66 | break; 67 | case CRunCommand::E_RUNCMD_CRASHED: 68 | emit errorDuringRun(errStr); 69 | return false; 70 | break; 71 | default: 72 | break; 73 | } 74 | 75 | finishOneStep(""); // for updating progress bar 76 | return true; 77 | } 78 | 79 | void CProjectUpdateThread::cancelUpdate() 80 | { 81 | bCancelUpdate_ = true; 82 | cmd_.cancelCommand(true); 83 | } 84 | 85 | int CProjectUpdateThread::countTotalRunCmd() 86 | { 87 | int i, totalCmd; 88 | QString cmdKey, cmdStr; 89 | 90 | CConfigManager* confManager; 91 | confManager = CConfigManager::getInstance(); 92 | 93 | totalCmd = 0; 94 | for (i = 1; i < MAX_SUPPORTED_RUN_COMMAND+1; i++) { 95 | cmdKey = QString("UpdateTagRunCmd") + QString::number(i); 96 | cmdStr = confManager->getAppSettingValue(cmdKey).toString(); 97 | 98 | if (cmdStr.isEmpty()) { // break if no more command to run 99 | break; 100 | } 101 | totalCmd = i; 102 | } 103 | return totalCmd; 104 | } 105 | 106 | int CProjectUpdateThread::createTag(QTagger& tagger, const T_FileItemList& inputFileList) 107 | { 108 | qsizetype i = 0; 109 | unsigned long fileId = 0; 110 | QString currentFilePath; 111 | 112 | qsizetype totalFile = inputFileList.size(); 113 | 114 | tagger.initKeywordFileTokenMap(); 115 | 116 | unsigned long long int totalFileSize = 0; 117 | unsigned long long int processedFileSize = 0; 118 | 119 | for (i = 0; i < totalFile; i++) { 120 | totalFileSize += inputFileList.at(i).fileSize_; 121 | } 122 | 123 | for (i = 0; i < totalFile; i++) { 124 | qDebug() << "inputFileList.at(i).fileName_ = " << inputFileList.at(i).fileName_ << Qt::endl; 125 | 126 | currentFilePath = inputFileList.at(i).fileName_; // index start from 0 127 | fileId = inputFileList.at(i).fileId_; 128 | 129 | qDebug() << fileId << ":" << currentFilePath; 130 | 131 | emit percentageCompleted(static_cast (static_cast (processedFileSize) / totalFileSize * 100), currentFilePath); 132 | 133 | qDebug() << "parseSourceFile IN" << Qt::endl; 134 | tagger.parseSourceFile(fileId, currentFilePath); 135 | qDebug() << "parseSourceFile OUT" << Qt::endl; 136 | 137 | processedFileSize += inputFileList.at(i).fileSize_; 138 | 139 | if (bCancelUpdate_) { 140 | emit cancelledTagBuild(); 141 | return 0; 142 | } 143 | } 144 | return 0; 145 | } 146 | 147 | void CProjectUpdateThread::run() 148 | { 149 | bool bRunResult; 150 | 151 | QString cmdKey, cmdStr; 152 | QString srcTagName, targetTagName; 153 | QString errStr; 154 | 155 | CConfigManager* confManager; 156 | confManager = CConfigManager::getInstance(); 157 | 158 | bCancelUpdate_ = false; 159 | 160 | // current directory 161 | QDir currentDir(QDir::currentPath()); 162 | 163 | // using absoluteFilePath so relative and absolute path also possible 164 | QString tmpDir = currentDir.absoluteFilePath(confManager->getAppSettingValue("TmpDir").toString()); 165 | 166 | // using absoluteFilePath so relative and absolute path also possible 167 | QString tagDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)+ "/tags/" + projectItem_.name_; 168 | QString tagName = "tags"; 169 | 170 | QString fileListFilename = tagDir + "/" + CSourceFileList::kFILE_LIST; 171 | 172 | initStep(countTotalRunCmd() + 2); // total run command + 2 (initial file list, tag update) 173 | 174 | if (!currentDir.exists(tagDir)) { 175 | currentDir.mkpath(tagDir); 176 | } 177 | 178 | if (!currentDir.exists(tmpDir)) { 179 | currentDir.mkpath(tmpDir); 180 | } 181 | 182 | /* first step, recursively list the source and header files to currentListFile */ 183 | QStringList nameFilters; 184 | QStringList srcMaskList = projectItem_.srcMask_.isEmpty() ? QStringList() : projectItem_.srcMask_.split(" "); 185 | QStringList headerMaskList = projectItem_.headerMask_.isEmpty() ? QStringList() : projectItem_.headerMask_.split(" "); 186 | 187 | nameFilters = srcMaskList + headerMaskList; 188 | 189 | QStringList dirToExcludeList = projectItem_.dirToExclude_.isEmpty() ? QStringList() : projectItem_.dirToExclude_.split(" "); 190 | QStringList fileMaskToExcludeList = projectItem_.fileMaskToExclude_.isEmpty() ? QStringList() : projectItem_.fileMaskToExclude_.split(" "); 191 | 192 | // create tag 193 | QTagger tagger; 194 | 195 | T_FileItemList resultFileList; 196 | 197 | QElapsedTimer timer; 198 | timer.start(); 199 | 200 | CSourceFileList::generateFileList(fileListFilename, projectItem_.srcDir_, nameFilters, resultFileList, dirToExcludeList, fileMaskToExcludeList); 201 | 202 | createTag(tagger, resultFileList); 203 | 204 | tagger.writeTagDb(tagDir + "/" + QTagger::kQTAG_DEFAULT_TAGDBNAME); 205 | 206 | qDebug() << "Tag creation took" << timer.elapsed() << "milliseconds"; 207 | 208 | finishOneStep(""); // for updating progress bar 209 | 210 | if (bCancelUpdate_) { 211 | emit cancelledTagBuild(); 212 | return; 213 | } 214 | 215 | finishOneStep(""); // for updating progress bar 216 | 217 | for (int i = 1; i < MAX_SUPPORTED_RUN_COMMAND+1; i++) { // from 1 to MAX_SUPPORTED_RUN_COMMAND 218 | cmdKey = QString("UpdateTagRunCmd") + QString::number(i); 219 | cmdStr = confManager->getAppSettingValue(cmdKey).toString(); 220 | 221 | if (cmdStr.isEmpty()) { // break if no more command to run 222 | qDebug() << "cmdStr empty, key: " << cmdKey << "str: " << cmdStr; 223 | break; 224 | } else { 225 | cmdStr.replace("$tmpList", fileListFilename); 226 | cmdStr.replace("$tagDir", tagDir); 227 | bRunResult = runCommand(cmdStr, projectItem_.srcDir_); 228 | if (!bRunResult) { // also break if errors during run 229 | break; 230 | } 231 | } 232 | } 233 | 234 | // for ctag 235 | if (bRunResult) { // only continue if runCommand without problem 236 | srcTagName = projectItem_.srcDir_ + "/" + tagName; 237 | targetTagName = tagDir + "/" + tagName; 238 | QFile::rename(srcTagName, targetTagName); 239 | //QFile::remove(srcTagName); 240 | finishAllStep(); // finish all step as it's the last one 241 | } 242 | 243 | return; 244 | } 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /Model/CProjectUpdateThread.h: -------------------------------------------------------------------------------- 1 | #ifndef CPROJECT_UPDATE_THREAD_H 2 | #define CPROJECT_UPDATE_THREAD_H 3 | 4 | #include 5 | #include 6 | 7 | #include "Utils/commonType.h" 8 | #include "Utils/CUtils.h" 9 | #include "Model/qTagger/qTagger.h" 10 | 11 | #include "Model/CProjectItem.h" 12 | #include "Model/CRunCommand.h" 13 | #include "Model/CConfigManager.h" 14 | #include "Model/qTagger/CSourceFileList.h" 15 | 16 | class CProjectUpdateThread: public QThread 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | CProjectUpdateThread(QObject *parent = 0); 22 | 23 | void setCurrentProjectItem(const CProjectItem& projectItem); 24 | void setRebuildTag(bool bRebuildTag); 25 | 26 | void run(); 27 | void cancelUpdate(); 28 | 29 | signals: 30 | void percentageCompleted(int percentage, QString indexingFileName); 31 | void cancelledTagBuild(); 32 | void errorDuringRun(const QString& errStr); 33 | 34 | private: 35 | 36 | bool runCommand(const QString& program, const QString& workDir, const QString& redirectFile = ""); 37 | 38 | void initStep(int totalStep); 39 | void finishOneStep(const QString& indexingFileName); 40 | void finishAllStep(); 41 | 42 | int countTotalRunCmd(); 43 | 44 | int createTag(QTagger& tagger, const T_FileItemList& inputFileList); 45 | 46 | CProjectItem projectItem_; 47 | 48 | CRunCommand cmd_; 49 | 50 | int stepCompleted_; 51 | int totalStep_; 52 | 53 | bool bCancelUpdate_; 54 | bool bRebuildTag_; 55 | 56 | static const int MAX_SUPPORTED_RUN_COMMAND = 999; 57 | 58 | }; 59 | 60 | #endif // CPROJECT_UPDATE_THREAD_H 61 | -------------------------------------------------------------------------------- /Model/CRunCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "CRunCommand.h" 2 | 3 | CRunCommand::CRunCommand() 4 | : MS_EACH_TIME_SLOT_WAIT(5000) // max wait for 5 second for each time slot 5 | { 6 | 7 | } 8 | 9 | CRunCommand::~CRunCommand() 10 | { 11 | 12 | 13 | } 14 | 15 | int CRunCommand::startRun(const QString& program, const QString& workDir, const QString& redirectFile, QString& errStr) 16 | { 17 | QProcess::ProcessError processErr = QProcess::UnknownError; 18 | bool bProcessNotRunning; 19 | QString outputStr; 20 | 21 | bCommandCancelled_ = false; 22 | 23 | qDebug() << "startCommand IN, cmd = (" << program << ")"; 24 | qDebug() << "workDir = " << workDir; 25 | 26 | QProcess extProcess; 27 | 28 | extProcess.setWorkingDirectory(workDir); 29 | if (redirectFile != "") { 30 | extProcess.setStandardOutputFile(redirectFile, QIODevice::Append); 31 | extProcess.setStandardErrorFile(redirectFile, QIODevice::Append); 32 | } 33 | 34 | extProcess.start(program); 35 | qDebug("Waiting process to start..."); 36 | 37 | bProcessNotRunning = false; 38 | 39 | // wait the process to start 40 | do { 41 | if (!(extProcess.waitForStarted(MS_EACH_TIME_SLOT_WAIT))) { 42 | processErr = extProcess.error(); 43 | qDebug("waitForStarted(), QProcess::error(): %d", processErr); 44 | } 45 | 46 | qDebug() << "process state = " << QString::number(int(extProcess.state())); 47 | 48 | // also break if process not running/finish running otherwise would result in busy loop 49 | if (extProcess.state() != QProcess::Running) { 50 | processErr = extProcess.error(); 51 | qDebug("process state != QProcess::Running, QProcess::error(): %d", processErr); 52 | 53 | bProcessNotRunning = true; 54 | break; 55 | } 56 | } while (((!bCommandCancelled_) && (processErr == QProcess::Timedout)) && (extProcess.state() != QProcess::Running)); 57 | 58 | qDebug("Process started, now running..."); 59 | 60 | if (processErr == QProcess::FailedToStart) { 61 | errStr = program + outputStr; 62 | return E_RUNCMD_FAILSTART; 63 | } 64 | 65 | if (bCommandCancelled_) { 66 | // kill the runnning process 67 | if (extProcess.state() == QProcess::Running) { 68 | extProcess.kill(); 69 | } 70 | return E_RUNCMD_CANCELLED; 71 | } 72 | if (bProcessNotRunning) { 73 | if (extProcess.exitStatus() == QProcess::CrashExit) { 74 | errStr = program; 75 | return E_RUNCMD_CRASHED; 76 | } 77 | } 78 | 79 | // wait the process to finish 80 | bProcessNotRunning = false; 81 | do { 82 | if (!(extProcess.waitForFinished(MS_EACH_TIME_SLOT_WAIT))) { 83 | processErr = extProcess.error(); 84 | qDebug("waitForFinished(), QProcess::error(): %d", processErr); 85 | } 86 | // also break if process not running/finish running otherwise would result in busy loop 87 | if (extProcess.state() != QProcess::Running) { 88 | bProcessNotRunning = true; 89 | break; 90 | } 91 | } while ((!bCommandCancelled_) && (processErr == QProcess::Timedout)); 92 | 93 | // User cancel, kill the runnning process 94 | if (bCommandCancelled_) { 95 | if (extProcess.state() == QProcess::Running) { 96 | extProcess.kill(); 97 | } 98 | 99 | return E_RUNCMD_CANCELLED; 100 | } 101 | 102 | if (bProcessNotRunning) { 103 | if (extProcess.exitStatus() == QProcess::CrashExit) { 104 | errStr = program; 105 | return E_RUNCMD_CRASHED; 106 | } 107 | } 108 | 109 | qDebug() << "startCommand OUT"; 110 | 111 | return E_RUNCMD_NO_ERROR; 112 | } 113 | 114 | int CRunCommand::cancelCommand(bool bCancel) 115 | { 116 | bCommandCancelled_ = true; 117 | return 0; 118 | } 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Model/CRunCommand.h: -------------------------------------------------------------------------------- 1 | #ifndef CRUN_COMMAND_H 2 | #define CRUN_COMMAND_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class CRunCommand 9 | { 10 | public: 11 | CRunCommand(); 12 | ~CRunCommand(); 13 | 14 | typedef enum {E_RUNCMD_NO_ERROR, E_RUNCMD_CANCELLED, E_RUNCMD_FAILSTART, E_RUNCMD_ERRRUN, E_RUNCMD_CRASHED} ENUM_RunCommandErr; 15 | 16 | int startRun(const QString& program, const QString& workDir, const QString& redirectFile, QString& errStr); 17 | 18 | int cancelCommand(bool bCancel); 19 | 20 | private: 21 | bool bCommandCancelled_; 22 | 23 | const int MS_EACH_TIME_SLOT_WAIT; 24 | 25 | }; 26 | 27 | #endif // CRUN_COMMAND_H 28 | 29 | 30 | -------------------------------------------------------------------------------- /Model/qFindReplacer/qFindReplacer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "qFindReplacer.h" 8 | 9 | QFindReplacer::QFindReplacer() 10 | { 11 | } 12 | 13 | QFindReplacer::~QFindReplacer() 14 | { 15 | 16 | } 17 | 18 | long QFindReplacer::replaceInFile(const QString& findStr, const QString& replaceStr, const QString& filePath, bool bCaseSensitive, bool bMatchWholeWord, bool bRegularExpression) 19 | { 20 | int i = 0; 21 | QString inputLine; 22 | QString replacedLine; 23 | long totalMatchCount = 0; 24 | long matchCount = 0; 25 | 26 | qDebug() << "Find and replace file: " << filePath << Qt::endl; 27 | 28 | QFile inputFile(filePath); 29 | QString outputFileName = filePath + ".tmp"; 30 | QFile outputFile(outputFileName); 31 | 32 | if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { 33 | qDebug() << "Cannot open inputFile file (" << filePath << ") for reading!" << Qt::endl; 34 | return -1; 35 | } 36 | 37 | if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Text)) { 38 | qDebug() << "Cannot open outputFile file (" << outputFileName << ") for writing!" << Qt::endl; 39 | return -1; 40 | } 41 | 42 | QTextStream inputFileStream(&inputFile); 43 | QTextStream outputFileStream(&outputFile); 44 | 45 | QRegularExpression regExp(findStr); 46 | 47 | Qt::CaseSensitivity caseSensitive; 48 | 49 | if (bCaseSensitive) { 50 | caseSensitive = Qt::CaseSensitive; 51 | // default expression default to case sensitive 52 | } else { 53 | caseSensitive = Qt::CaseInsensitive; 54 | regExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption); 55 | } 56 | 57 | if (bRegularExpression || bMatchWholeWord) { 58 | // match whole word take effect only when regular expression is not enabled 59 | if (bMatchWholeWord && !bRegularExpression) { 60 | regExp.setPattern("\\b" + findStr + "\\b"); 61 | } 62 | while (!inputFileStream.atEnd()) { 63 | inputLine = inputFileStream.readLine(); 64 | 65 | matchCount = inputLine.count(regExp); 66 | 67 | if (matchCount > 0) { 68 | replacedLine = inputLine.replace(regExp, replaceStr); 69 | outputFileStream << replacedLine << Qt::endl; 70 | totalMatchCount += matchCount; 71 | } else { 72 | outputFileStream << inputLine << Qt::endl; 73 | } 74 | } 75 | } else { 76 | while (!inputFileStream.atEnd()) { 77 | inputLine = inputFileStream.readLine(); 78 | 79 | matchCount = inputLine.count(findStr, caseSensitive); 80 | if (matchCount > 0) { 81 | replacedLine = inputLine.replace(findStr, replaceStr, caseSensitive); 82 | outputFileStream << replacedLine << Qt::endl; 83 | totalMatchCount += matchCount; 84 | } else { 85 | outputFileStream << inputLine << Qt::endl; 86 | } 87 | 88 | } 89 | } 90 | 91 | if (totalMatchCount > 0) { 92 | inputFile.remove(); // remove the original file 93 | outputFile.close(); 94 | QFile::rename(outputFileName, filePath); // move the temporary file as input file 95 | } else { 96 | outputFile.remove(); // remove temporary file as no replace taken place 97 | inputFile.close(); // no action for input file 98 | } 99 | 100 | 101 | return totalMatchCount; 102 | } 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /Model/qFindReplacer/qFindReplacer.h: -------------------------------------------------------------------------------- 1 | #ifndef QFIND_REPLACER_H 2 | #define QFIND_REPLACER_H 3 | 4 | #include 5 | #include 6 | 7 | class QFindReplacer 8 | { 9 | public: 10 | QFindReplacer(); 11 | virtual ~QFindReplacer(); 12 | 13 | // return number of matched and replaced 14 | long replaceInFile(const QString& findStr, const QString& replaceStr, const QString& filePath, bool bCaseSensitive, bool bMatchWholeWord, bool bRegularExpression); 15 | 16 | }; 17 | 18 | #endif 19 | 20 | 21 | -------------------------------------------------------------------------------- /Model/qTagger/CSourceFileList.cpp: -------------------------------------------------------------------------------- 1 | #include "CSourceFileList.h" 2 | 3 | const char* CSourceFileList::kFILE_LIST= "fileList.txt"; 4 | 5 | CSourceFileList::CSourceFileList() 6 | { 7 | 8 | 9 | } 10 | 11 | CSourceFileList::~CSourceFileList() 12 | { 13 | 14 | } 15 | 16 | int CSourceFileList::loadFileList(const QString& fileListFilename, T_FileItemList& resultFileList) 17 | { 18 | bool bListFileOpenResult; 19 | QFile currentListFile(fileListFilename); 20 | CFileItem fileItem; 21 | QString lineItem; 22 | 23 | bListFileOpenResult = currentListFile.open(QIODevice::ReadOnly | QIODevice::Text); 24 | 25 | if (!bListFileOpenResult) { 26 | qDebug() << "Cannot open list file (" << fileListFilename << ") for reading!" << Qt::endl; 27 | return -1; 28 | } 29 | 30 | QTextStream listFileStream(¤tListFile); 31 | 32 | QString lastFilePath = ""; 33 | int filePathIndex = 0; 34 | 35 | QString currentFileName = ""; 36 | QString currentPath = ""; 37 | 38 | QString currentEntry = ""; 39 | 40 | if (bListFileOpenResult) { 41 | while (!listFileStream.atEnd()) { 42 | lineItem = listFileStream.readLine(); 43 | lineItem = lineItem.trimmed(); 44 | 45 | // start, end section 46 | fileItem.fileId_ = lineItem.section('\t', 0, 0).toLong(); 47 | currentEntry = lineItem.section('\t', 1, 1); 48 | 49 | filePathIndex = currentEntry.lastIndexOf("/"); 50 | if (filePathIndex >= 0) { // full path 51 | fileItem.fileName_ = currentEntry; 52 | lastFilePath = currentEntry.left(filePathIndex); // index start from 0, exclude separator 53 | } else { 54 | fileItem.fileName_ = lastFilePath + "/" + currentEntry; 55 | } 56 | 57 | fileItem.fileLastModified_ = lineItem.section('\t', 2, 2); 58 | fileItem.fileSize_ = lineItem.section('\t', 3, 3).toULongLong(); 59 | 60 | resultFileList << fileItem; 61 | } 62 | currentListFile.close(); 63 | return 0; 64 | } 65 | return 0; 66 | } 67 | 68 | int CSourceFileList::saveFileList(const QString& fileListFilename, const QMap& resultFileList) 69 | { 70 | QFile currentListFile(fileListFilename); 71 | 72 | if (!currentListFile.open(QIODevice::WriteOnly | QIODevice::Text)) { 73 | qDebug() << "Cannot open list file (" << fileListFilename << ") for writing!" << Qt::endl; 74 | } 75 | 76 | QTextStream listFileStream(¤tListFile); 77 | 78 | CFileItem fileItem; 79 | 80 | QString lastFilePath = ""; 81 | int filePathIndex = 0; 82 | 83 | QString currentFileName = ""; 84 | QString currentPath = ""; 85 | 86 | foreach (const CFileItem& fileItem, resultFileList) { 87 | // file id 88 | listFileStream << QString::number(fileItem.fileId_); 89 | listFileStream << "\t"; 90 | 91 | // filename 92 | filePathIndex = fileItem.fileName_.lastIndexOf(QDir::separator()); 93 | if (filePathIndex >= 0) { 94 | currentFileName = fileItem.fileName_.mid(filePathIndex + 1); // exclude separator 95 | currentPath = fileItem.fileName_.left(filePathIndex); 96 | 97 | if (currentPath == lastFilePath) { 98 | listFileStream << currentFileName; 99 | } else { 100 | listFileStream << currentPath; 101 | lastFilePath = currentPath; 102 | } 103 | } 104 | 105 | listFileStream << "\t"; 106 | 107 | // last modified datetime 108 | listFileStream << fileItem.fileLastModified_; 109 | listFileStream << "\t"; 110 | 111 | // file size 112 | listFileStream << QString::number(fileItem.fileSize_); 113 | listFileStream << "\n"; 114 | } 115 | 116 | currentListFile.flush(); 117 | currentListFile.close(); 118 | return 0; 119 | } 120 | 121 | bool isBinaryFile(const QString& filePath) { 122 | QFile file(filePath); 123 | if (!file.open(QIODevice::ReadOnly)) { 124 | qDebug() << "Cannot open file (" << filePath << ") for reading!" << Qt::endl; 125 | return false; 126 | } 127 | 128 | QByteArray fileData = file.read(1024); // Read the first 1024 bytes 129 | file.close(); 130 | 131 | // Check for Unicode BOM header 132 | if (fileData.startsWith("\xEF\xBB\xBF") || // UTF-8 BOM 133 | fileData.startsWith("\xFF\xFE") || // UTF-16 (LE) BOM 134 | fileData.startsWith("\xFE\xFF")) { // UTF-16 (BE) BOM 135 | return false; 136 | } 137 | 138 | // Check for binary content 139 | for (char byte : fileData) { 140 | if (byte == '\0') { 141 | return true; 142 | } 143 | } 144 | 145 | return false; 146 | } 147 | 148 | 149 | int CSourceFileList::generateFileList(const QString& resultFilename, const QString& srcDir, const QStringList& nameFilters, T_FileItemList& resultFileList, const QStringList& defaultDirsToExclude, const QStringList& defaultFileMasksToExclude, bool bSaveToFile) 150 | { 151 | QFile currentListFile(resultFilename); 152 | 153 | QTextStream listFileStream; 154 | 155 | if (bSaveToFile) { 156 | if (!currentListFile.open(QIODevice::WriteOnly | QIODevice::Text)) { 157 | qDebug() << "Cannot open list file (" << resultFilename << ") for writing!" << Qt::endl; 158 | } 159 | 160 | listFileStream.setDevice(¤tListFile); 161 | } 162 | 163 | QDirIterator iter(srcDir, nameFilters, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories|QDirIterator::FollowSymlinks); 164 | CFileItem fileItem; 165 | QString lastModifiedDateTime; 166 | QString fileSizeStr; 167 | 168 | long fileId = 0; 169 | 170 | QString lastFilePath = ""; 171 | 172 | QString filePath; 173 | QString currentFilePath; 174 | QString currentFileName; 175 | 176 | QStringList fileList; 177 | 178 | while (iter.hasNext()) { 179 | filePath = iter.next(); 180 | 181 | currentFilePath = QFileInfo(filePath).path(); 182 | currentFileName = QFileInfo(filePath).fileName(); 183 | 184 | bool excludeDir = false, excludeFile = false; 185 | 186 | for (const QString& dirToExclude : defaultDirsToExclude) { 187 | if (currentFilePath.startsWith(srcDir + "/" + dirToExclude)) { 188 | excludeDir = true; 189 | break; 190 | } 191 | } 192 | 193 | if (!excludeDir) { 194 | for (const QString& fileMaskToExclude : defaultFileMasksToExclude) { 195 | QRegularExpression regExp(QRegularExpression::wildcardToRegularExpression(fileMaskToExclude), QRegularExpression::CaseInsensitiveOption); 196 | if (regExp.match(currentFileName).hasMatch()) { 197 | excludeFile = true; 198 | break; 199 | } 200 | } 201 | } 202 | 203 | if (excludeFile || excludeDir) { 204 | qDebug() << "Excluded file: " << currentFilePath << "/" << currentFileName; 205 | continue; 206 | } 207 | 208 | fileList << filePath; 209 | } 210 | 211 | for (const QString& filePath : fileList) { 212 | if (isBinaryFile(filePath)) { // skip binary file 213 | qDebug() << "Binary file: " << filePath; 214 | continue; 215 | } 216 | 217 | QFileInfo fileInfo = QFileInfo(filePath); 218 | fileItem.fileName_ = filePath; 219 | 220 | fileInfo.setCaching(false); 221 | 222 | fileItem.fileId_ = fileId; 223 | 224 | lastModifiedDateTime = fileInfo.lastModified().toString("dd/MM/yyyy hh:mm:ss"); 225 | fileItem.fileLastModified_ = lastModifiedDateTime; // update fileItem last modified datetime 226 | 227 | fileItem.fileSize_ = fileInfo.size(); // update fileItem file size 228 | 229 | if (bSaveToFile) { 230 | // file id 231 | listFileStream << QString::number(fileItem.fileId_); 232 | listFileStream << "\t"; 233 | 234 | // filename; write filename only if same path as previous one 235 | if (fileInfo.path() == lastFilePath) { 236 | listFileStream << fileInfo.fileName(); 237 | } else { 238 | listFileStream << fileItem.fileName_; 239 | lastFilePath = fileInfo.path(); // update last path 240 | } 241 | listFileStream << "\t"; 242 | 243 | // last modified datetime 244 | listFileStream << lastModifiedDateTime; 245 | listFileStream << "\t"; 246 | 247 | // file size 248 | listFileStream << QString::number(fileItem.fileSize_); 249 | listFileStream << "\n"; 250 | 251 | listFileStream.flush(); 252 | } 253 | 254 | // append to result file list 255 | resultFileList << fileItem; 256 | 257 | fileId++; 258 | } 259 | 260 | if (bSaveToFile) { 261 | currentListFile.close(); 262 | } 263 | 264 | return 0; 265 | } 266 | 267 | 268 | 269 | 270 | 271 | -------------------------------------------------------------------------------- /Model/qTagger/CSourceFileList.h: -------------------------------------------------------------------------------- 1 | #ifndef CSOURCE_FILE_LIST_H 2 | #define CSOURCE_FILE_LIST_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "../CFileItem.h" 15 | 16 | typedef QList T_FileItemList; 17 | 18 | class CSourceFileList 19 | { 20 | public: 21 | CSourceFileList(); 22 | ~CSourceFileList(); 23 | 24 | static int loadFileList(const QString& fileListFilename, T_FileItemList& resultFileList); 25 | static int saveFileList(const QString& fileListFilename, const QMap& resultFileList); 26 | 27 | static int generateFileList(const QString& resultFilename, const QString& srcDir, const QStringList& nameFilters, T_FileItemList& resultFileList, const QStringList& defaultDirsToExclude, const QStringList& defaultFileMasksToExclude, bool bSaveToFile = true); 28 | 29 | static const char* kFILE_LIST; 30 | }; 31 | 32 | 33 | 34 | #endif // CSOURCE_FILE_LIST_H 35 | 36 | 37 | -------------------------------------------------------------------------------- /Model/qTagger/CTagFileRecord.cpp: -------------------------------------------------------------------------------- 1 | #include "CTagFileRecord.h" 2 | 3 | CTagFileRecord::CTagFileRecord() 4 | { 5 | fileId_ = 0; 6 | } 7 | 8 | CTagFileRecord::CTagFileRecord(unsigned fileId, const QList& lineNum) 9 | { 10 | fileId_ = fileId; 11 | lineNum_ = lineNum; 12 | } 13 | -------------------------------------------------------------------------------- /Model/qTagger/CTagFileRecord.h: -------------------------------------------------------------------------------- 1 | #ifndef CTAG_FILE_RECORD_H_ 2 | #define CTAG_FILE_RECORD_H_ 3 | 4 | #include 5 | 6 | class CTagFileRecord 7 | { 8 | public: 9 | 10 | CTagFileRecord(); 11 | CTagFileRecord(unsigned fileId, const QList& lineNum); 12 | 13 | virtual ~CTagFileRecord() {}; 14 | 15 | unsigned long fileId_; 16 | QList lineNum_; 17 | }; 18 | 19 | #endif // CTAG_FILE_RECORD_H_ 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Model/qTagger/CTagItem.cpp: -------------------------------------------------------------------------------- 1 | #include "CTagItem.h" 2 | 3 | CTagItem::CTagItem() 4 | { 5 | tag_ = ""; 6 | } 7 | 8 | CTagItem::CTagItem(const QString& tag, const QVector& tagFileRecord) 9 | { 10 | tag_ = tag; 11 | tagFileRecord_ = tagFileRecord; 12 | } 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Model/qTagger/CTagItem.h: -------------------------------------------------------------------------------- 1 | #ifndef CTAG_ITEM_H 2 | #define CTAG_ITEM_H 3 | 4 | #include 5 | #include "CTagFileRecord.h" 6 | 7 | class CTagItem 8 | { 9 | public: 10 | 11 | CTagItem(); 12 | CTagItem(const QString& tag, const QVector& tagFileRecord); 13 | 14 | virtual ~CTagItem() {}; 15 | 16 | QString tag_; 17 | QVector tagFileRecord_; 18 | }; 19 | 20 | #endif // CTAG_ITEM_H 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Model/qTagger/CTagResultItem.cpp: -------------------------------------------------------------------------------- 1 | #include "CTagResultItem.h" 2 | 3 | const char* CTagResultItem::kFIELD_RESULT_SEPERATOR = ":"; 4 | 5 | CTagResultItem::CTagResultItem() 6 | { 7 | 8 | } 9 | 10 | CTagResultItem::~CTagResultItem() 11 | { 12 | 13 | } 14 | 15 | ostream& operator<<(ostream& ost, const CTagResultItem& item) 16 | { 17 | QString resultStr = (item.filePath_ + CTagResultItem::kFIELD_RESULT_SEPERATOR + QString::number(item.fileLineNum_) + CTagResultItem::kFIELD_RESULT_SEPERATOR + item.fileLineSrc_); 18 | 19 | ost << resultStr.toStdString(); 20 | 21 | return ost; 22 | } 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Model/qTagger/CTagResultItem.h: -------------------------------------------------------------------------------- 1 | #ifndef CTAG_RESULT_ITEM_H 2 | #define CTAG_RESULT_ITEM_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | using namespace std; 9 | 10 | class CTagResultItem 11 | { 12 | public: 13 | CTagResultItem(); 14 | virtual ~CTagResultItem(); 15 | 16 | QString filePath_; 17 | unsigned long fileLineNum_; 18 | QString fileLineSrc_; 19 | 20 | QStringList fileLineSrcBeforeList_; 21 | int lineSrcIndentLevel_; 22 | QStringList fileLineSrcAfterList_; 23 | 24 | QList beforeIndentLevelList_; 25 | QList afterIndentLevelList_; 26 | 27 | QString functionSignature_; 28 | 29 | static const char* kFIELD_RESULT_SEPERATOR; 30 | 31 | }; 32 | 33 | ostream& operator<<(ostream& ost, const CTagResultItem& item); 34 | 35 | #endif // CTAG_RESULT_ITEM_H 36 | 37 | -------------------------------------------------------------------------------- /Model/qTagger/qTagger.h: -------------------------------------------------------------------------------- 1 | #ifndef QTAGGER_H 2 | #define QTAGGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "commonType.h" 15 | #include "CUtils.h" 16 | #include "CTagResultItem.h" 17 | 18 | #include "CSourceFileList.h" 19 | 20 | #include "CTagItem.h" 21 | 22 | typedef QHash T_TokenMapType; 23 | 24 | class QTagger 25 | { 26 | public: 27 | QTagger(); 28 | virtual ~QTagger(); 29 | 30 | int initKeywordFileTokenMap(); 31 | 32 | int createTag(const T_FileItemList& inputFileList); 33 | int writeTagDb(const QString& tagDbFileName); 34 | 35 | int loadTagList(const QString& tagDbFileName); 36 | 37 | int levenshteinDistance(const QString &source, const QString &target); 38 | 39 | bool fuzzyMatch(const QString& targetInput, const QString& patternInput, const Qt::CaseSensitivity& caseSensitivity); 40 | int getFuzzyMatchedTags(const QString& tagToQuery, QMultiMap& matchedTokenList, const Qt::CaseSensitivity& caseSensitivity); 41 | 42 | int getMatchedTags(const QString& tagToQuery, QMultiMap& matchedTokenList, const Qt::CaseSensitivity& caseSensitivity); 43 | 44 | int queryTagLoadedSymbol(const T_FileItemList& inputFileItemList, const QString& tagToQuery, 45 | QString& tagToQueryFiltered, QList& resultList, const Qt::CaseSensitivity& caseSensitivity, bool symbolRegularExpression, unsigned long limitSearchRow); 46 | 47 | int queryTag(const QString& inputFileName, const QString& tagDbFileName, const QString& tagToQuery, 48 | QString& tagToQueryFiltered, QList& resultList, const Qt::CaseSensitivity& caseSensitivity, bool symbolRegularExpression); 49 | 50 | bool parseSourceFile(unsigned long fileId, const QString& fileName, T_TokenMapType& tokenMap); 51 | bool parseSourceFile(unsigned long fileId, const QString& fileName); 52 | 53 | static const char* kQTAG_CONFIG_FILE; 54 | static const char* kDB_FIELD_LINE_SEPERATOR; 55 | static const char* kDB_FIELD_FILE_SEPERATOR; 56 | static const char* kDB_FIELD_FILE_RECORD_SEPERATOR; 57 | static const char* kDB_TAG_RECORD_SEPERATOR; 58 | 59 | static const char* kDB_FIELD_RESULT_SEPERATOR; 60 | 61 | static const char* kQTAG_DEFAULT_TAGDBNAME; 62 | 63 | static const char* kQTAG_DEFAULT_INPUTLIST_FILE; 64 | 65 | static const long kTAG_LENGTH_LIMIT = 20000; 66 | 67 | private: 68 | 69 | void extractWordTokens(const QString& str, QStringList& tokenList); 70 | 71 | void loadKeywordFile(); 72 | 73 | QSet keywordSet_; 74 | 75 | QVector tagList_; 76 | 77 | T_TokenMapType tokenMap_; 78 | 79 | int getFileLineContent(const QString& fileName, const QList& lineNumList, QList& resultLineList, 80 | const QStringList& lineFilterStrList, const QStringList& excludePatternFilterStrList, 81 | int linePrintBeforeMatch, int linePrintAfterMatch, const Qt::CaseSensitivity& caseSensitivity, unsigned long limitSearchRow); 82 | 83 | 84 | 85 | }; 86 | 87 | #endif 88 | 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Blink logo](https://raw.githubusercontent.com/ychclone/blink/master/Resources/Images/graphics3.png) 2 | 3 | # Blink code search 4 | GUI of indexed grep in Windows and Linux. A source code indexing tool, near instant code search tool and navigation. Good for small to medium size code base. It supports fuzzy matching, auto complete, 5 | and live grep for real time query. 6 | Manage different projects and switch for different projects 7 | Drag and drop of filenames to your favourite editor. 8 | 9 | [![Build status](https://ci.appveyor.com/api/projects/status/afn8q3ai3e7wphrf?svg=true)](https://ci.appveyor.com/project/ychclone/blink) 10 | 11 | # Screenshots 12 | ![Screencast](https://raw.githubusercontent.com/ychclone/blink/master/Screencast/Usage.gif) 13 | 14 | # Features 15 | * Fast search using prebuilt index 16 | * Fuzzy suggestion in autocomplete 17 | * Live grep 18 | * Drag and drop for filename to your favourite editor 19 | * Switch between multiple projects 20 | * Very small index size compared to trigram 21 | * Replaces in files for searched symbol 22 | * Cross platform 23 | 24 | # Download, Install 25 | 26 | Windows and Linux binaries are available in 27 | * https://sourceforge.net/projects/blink-code-search/files/ 28 | 29 | Source code is avaliable in 30 | * https://github.com/ychclone/blink 31 | 32 | # Change Log 33 | 34 | ## version [1.10.0] 2024/09/10 35 | 36 | - Editor can go back and forward for navigation 37 | - Advanced option in search combo box 38 | - Right click close all tab, close all to left, close all to right, copy file path, copy filename, and copy file 39 | - Detect if file opened got modification by other program and prompt reload 40 | - Fix for find before line match 41 | - Fix for cursor line highlight 42 | - Fix for symbol regular expression escaped html string 43 | 44 | ## version [1.9.4] 2024/08/23 45 | 46 | - Change default source mask from \*.\* to \* to include file without extension 47 | 48 | ## version [1.9.3] 2024/08/21 49 | 50 | - Support directory to exclude and file mask to exclude 51 | 52 | ## version [1.9.2] 2024/08/07 53 | 54 | - can now use \*.\* as source file mask to process all text file. Binary files will be skipped. 55 | - default source file mask set to \*.\* 56 | 57 | # Code search 58 | ![Code search](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_codesearch.png) 59 | 60 | # File listing 61 | ![File listing](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_filelisting.png) 62 | 63 | # Usage 64 | 65 | 1. Drop the folder (e.g. from file explorer, nautilus) into the window below 66 | project tab. 67 | ![Drop folder](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/usage_drop_folder.png) 68 | 69 | 2. A new project dialog will appears. Type the file extensions that you want to index. 70 | 71 | 72 | 73 | 3. Right click on the project name 74 | 4. Click "Rebuild Symbol" 75 | 5. Double click the project name to make it the active project. 76 | Or right click and select "Load" 77 | 78 | ![Load project](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/usage_load_project.png) 79 | 80 | 6. Start file filtering and code search on the file and symbol tab 81 | 82 | # Advanced Usage 83 | 84 | For symbol queries, advanced options can be entered: 85 | There is no spacing in between e.g. /a10, /n3, /xinclude 86 | 87 | * /a NumberOfLinesAfter 88 | * /b NumberOfLinesBefore 89 | * /n NumberOfLinesBeforeAndAFter 90 | * /f FileNameToMatch 91 | * /x PatternToExclude 92 | 93 | In addition, regular expression can be entered for the queries: 94 | e.g. .*mainWindows, (_clicked|_Pressed) 95 | It will match all ("and" condition) if multiple symbols are entered for 96 | queries. 97 | 98 | # Configuration 99 | 100 | The text editor when double clicking the filename in file tab 101 | could be set in configuration. The filename could be dropped to 102 | other editor. 103 | Option->Setting->Main->Default Editor 104 | 105 | # Tips 106 | 107 | ## Display result lines before and after 108 | In the text field for symbol, "/n3" could be used to display 3 lines before and after 109 | ![Multiple lines](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_multiple_lines.png) 110 | 111 | ## Match for multiple symbol 112 | Multiple symbols (and condition) could be input for symbol queries. 113 | e.g. Multiple match are input "CMainWindow", "_on" as queries. 114 | ![Multiple symbols](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_multiple_symbols.png) 115 | 116 | ## Show multiple project 117 | Regular expression could be used to filter the project name and source filename name. 118 | e.g. "Or" condition for project name using the pipe "|" regular expression. 119 | ![Regular expression](https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_regular_expression.png) 120 | 121 | # Troubleshooting 122 | 123 | ## /usr/bin/ld: cannot find -lGL; collect2: error: ld returned 1 exit status 124 | Sol: sudo apt install libgl1-mesa-dev 125 | 126 | ## Qt version not match 127 | ``` 128 | sudo rm /usr/bin/qmake 129 | sudo ln -s /home/ychclone/Qt5.14.2/5.14.2/gcc_64/bin/qmake /usr/bin/qmake 130 | ``` 131 | 132 | ## Segmentation fault (core dumped) when start 133 | Please cp ./blink to build directory. 134 | Please make sure the following config files existed in build directory: 135 | - blink.ini 136 | - qtag.conf 137 | - qt.conf 138 | - record.xml 139 | 140 | ## qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in "" 141 | Error message: This application failed to start because no Qt platform plugin 142 | could be initialized. Reinstalling the application may fix this problem. 143 | 144 | Sol: 145 | ``` 146 | export QT_QPA_PLATFORM_PLUGIN_PATH=/home/ychclone/Qt5.14.2/5.14.2/gcc_64/plugins/platforms 147 | ``` 148 | 149 | 150 | -------------------------------------------------------------------------------- /Resources/Forms/aboutDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | aboutDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 678 10 | 286 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 369 22 | 157 23 | 24 | 25 | 26 | Qt::DefaultContextMenu 27 | 28 | 29 | About 30 | 31 | 32 | 33 | 6 34 | 35 | 36 | 6 37 | 38 | 39 | 6 40 | 41 | 42 | 6 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | :/Images/graphics3.png 53 | 54 | 55 | true 56 | 57 | 58 | Qt::AlignCenter 59 | 60 | 61 | false 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Blink v1.10.1 71 | 72 | 73 | 74 | 75 | 76 | 77 | <html><head/><body><p><a href="https://github.com/ychclone/blink"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/ychclone/blink</span></a></p><p><a href="https://github.com/ychclone/blink"><span style=" text-decoration: underline; color:#0000ff;">https://sourceforge.net/projects/blink-code-search/</span></a></p></body></html> 78 | 79 | 80 | true 81 | 82 | 83 | 84 | 85 | 86 | 87 | (c) 2024 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Qt::Horizontal 97 | 98 | 99 | 100 | 40 101 | 20 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | Qt::Horizontal 112 | 113 | 114 | 115 | 40 116 | 20 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | Qt::Vertical 125 | 126 | 127 | 128 | 20 129 | 40 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | Qt::Vertical 138 | 139 | 140 | 141 | 20 142 | 40 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /Resources/Forms/editor.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | editor 4 | 5 | 6 | 7 | 0 8 | 0 9 | 406 10 | 179 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | QWidget {background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #f6f9fe, stop:0.05 #e1eaf9, stop:0.5 #d9dee7 , stop:0.8 #b6c1d0, stop: 1 #e1eaf9);} 18 | 19 | 20 | 21 | 22 | 23 | -1 24 | 25 | 26 | true 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Resources/Forms/findReplaceDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | findReplaceDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 910 10 | 636 11 | 12 | 13 | 14 | Replace in files 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Match whole word only 26 | 27 | 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | Case Sensitive 36 | 37 | 38 | true 39 | 40 | 41 | 42 | 43 | 44 | 45 | Regular Expression 46 | 47 | 48 | 49 | 50 | 51 | 52 | Qt::Horizontal 53 | 54 | 55 | 56 | 40 57 | 20 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | Qt::Horizontal 70 | 71 | 72 | 73 | 40 74 | 20 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Select All 83 | 84 | 85 | false 86 | 87 | 88 | 89 | 90 | 91 | 92 | Clear All 93 | 94 | 95 | true 96 | 97 | 98 | false 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Find: 110 | 111 | 112 | 113 | 114 | 115 | 116 | Replace: 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | Qt::Horizontal 134 | 135 | 136 | 137 | 40 138 | 20 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | Replace 147 | 148 | 149 | false 150 | 151 | 152 | 153 | 154 | 155 | 156 | Cancel 157 | 158 | 159 | false 160 | 161 | 162 | 163 | 164 | 165 | 166 | Qt::Horizontal 167 | 168 | 169 | 170 | 40 171 | 20 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | QAbstractItemView::SingleSelection 182 | 183 | 184 | 185 | 186 | 187 | 188 | 24 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | Qt::Horizontal 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | :/Icons/22x22/edit-4.png:/Icons/22x22/edit-4.png 207 | 208 | 209 | Edit 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /Resources/Icons/22x22/code-class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/code-class.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/document-new-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/document-new-4.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/document-open-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/document-open-6.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/document-open-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/document-open-folder.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/edit-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/edit-4.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/edit-add-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/edit-add-4.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/edit-copy-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/edit-copy-4.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/edit-remove-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/edit-remove-3.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-about.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-cancel.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-delete.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-execute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-execute.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-new.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-ok.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-properties.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-redo-ltr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-redo-ltr.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/gtk-refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/gtk-refresh.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/insert-link-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/insert-link-2.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/view-process-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/view-process-all.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/xconsole-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/xconsole-2.png -------------------------------------------------------------------------------- /Resources/Icons/22x22/zoom-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/22x22/zoom-3.png -------------------------------------------------------------------------------- /Resources/Icons/48x48/application-x-gnome-saved-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/48x48/application-x-gnome-saved-search.png -------------------------------------------------------------------------------- /Resources/Icons/48x48/applications-graphics-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/48x48/applications-graphics-5.png -------------------------------------------------------------------------------- /Resources/Icons/48x48/applications-system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/48x48/applications-system.png -------------------------------------------------------------------------------- /Resources/Icons/48x48/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/48x48/forward.png -------------------------------------------------------------------------------- /Resources/Icons/appIcons.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE graphics3.ico 2 | -------------------------------------------------------------------------------- /Resources/Icons/graphics.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/graphics.ico -------------------------------------------------------------------------------- /Resources/Icons/graphics2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/graphics2.ico -------------------------------------------------------------------------------- /Resources/Icons/graphics3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/graphics3.ico -------------------------------------------------------------------------------- /Resources/Icons/text-x-preview.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Icons/text-x-preview.ico -------------------------------------------------------------------------------- /Resources/Images/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/copy.png -------------------------------------------------------------------------------- /Resources/Images/cut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/cut.png -------------------------------------------------------------------------------- /Resources/Images/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/file.png -------------------------------------------------------------------------------- /Resources/Images/graphics16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/graphics16x16.png -------------------------------------------------------------------------------- /Resources/Images/graphics2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/graphics2.png -------------------------------------------------------------------------------- /Resources/Images/graphics3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/graphics3.png -------------------------------------------------------------------------------- /Resources/Images/graphics32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/graphics32x32.png -------------------------------------------------------------------------------- /Resources/Images/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/group.png -------------------------------------------------------------------------------- /Resources/Images/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/new.png -------------------------------------------------------------------------------- /Resources/Images/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/open.png -------------------------------------------------------------------------------- /Resources/Images/paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/paste.png -------------------------------------------------------------------------------- /Resources/Images/project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/project.png -------------------------------------------------------------------------------- /Resources/Images/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/save.png -------------------------------------------------------------------------------- /Resources/Images/symbol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Resources/Images/symbol.png -------------------------------------------------------------------------------- /Resources/app.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Images/group.png 4 | Images/file.png 5 | Images/project.png 6 | Images/symbol.png 7 | Icons/22x22/document-open-folder.png 8 | Icons/22x22/edit-4.png 9 | Icons/22x22/edit-add-4.png 10 | Icons/22x22/edit-remove-3.png 11 | Icons/22x22/zoom-3.png 12 | Icons/22x22/code-class.png 13 | Icons/22x22/document-new-4.png 14 | Icons/22x22/document-open-6.png 15 | Icons/22x22/view-process-all.png 16 | Icons/22x22/edit-copy-4.png 17 | Icons/22x22/xconsole-2.png 18 | Icons/22x22/insert-link-2.png 19 | Icons/48x48/applications-graphics-5.png 20 | Images/graphics2.png 21 | Icons/22x22/gtk-about.png 22 | Icons/48x48/application-x-gnome-saved-search.png 23 | Icons/48x48/applications-system.png 24 | Icons/48x48/forward.png 25 | Icons/22x22/gtk-execute.png 26 | Icons/22x22/gtk-cancel.png 27 | Icons/text-x-preview.ico 28 | Icons/22x22/gtk-delete.png 29 | Icons/22x22/gtk-new.png 30 | Icons/22x22/gtk-ok.png 31 | Icons/22x22/gtk-properties.png 32 | Icons/22x22/gtk-redo-ltr.png 33 | Icons/22x22/gtk-refresh.png 34 | Images/graphics32x32.png 35 | Images/graphics3.png 36 | Images/save.png 37 | Images/paste.png 38 | Images/open.png 39 | Images/new.png 40 | Images/cut.png 41 | Images/copy.png 42 | 43 | 44 | -------------------------------------------------------------------------------- /Resources/webview.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Scripts/google-code-prettify/prettify.css 4 | Scripts/google-code-prettify/prettify.js 5 | 6 | 7 | -------------------------------------------------------------------------------- /Screencast/Usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screencast/Usage.gif -------------------------------------------------------------------------------- /Screenshot/blink_codesearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/blink_codesearch.png -------------------------------------------------------------------------------- /Screenshot/blink_filelisting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/blink_filelisting.png -------------------------------------------------------------------------------- /Screenshot/blink_multiple_lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/blink_multiple_lines.png -------------------------------------------------------------------------------- /Screenshot/blink_multiple_symbols.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/blink_multiple_symbols.png -------------------------------------------------------------------------------- /Screenshot/blink_regular_expression.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/blink_regular_expression.png -------------------------------------------------------------------------------- /Screenshot/blink_replaceinfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/blink_replaceinfiles.png -------------------------------------------------------------------------------- /Screenshot/usage_drop_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/usage_drop_folder.png -------------------------------------------------------------------------------- /Screenshot/usage_load_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/usage_load_project.png -------------------------------------------------------------------------------- /Screenshot/usage_new_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Screenshot/usage_new_project.png -------------------------------------------------------------------------------- /Setup/blinkSetup.iss: -------------------------------------------------------------------------------- 1 | ; Script generated by the Inno Setup Script Wizard. 2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! 3 | 4 | #define MyAppName "Blink" 5 | #define MyAppVersion "1.10.1" 6 | #define MyAppPublisher "ychclone" 7 | #define MyAppURL "https://github.com/ychclone/blink" 8 | #define MyAppExeName "blink.exe" 9 | 10 | [Setup] 11 | ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. 12 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) 13 | AppId={{EA02F721-E418-4743-A996-624147EBD6E2} 14 | AppName={#MyAppName} 15 | AppVersion={#MyAppVersion} 16 | ;AppVerName={#MyAppName} {#MyAppVersion} 17 | AppPublisher={#MyAppPublisher} 18 | AppPublisherURL={#MyAppURL} 19 | AppSupportURL={#MyAppURL} 20 | AppUpdatesURL={#MyAppURL} 21 | DefaultDirName={autopf}\Blink 22 | DisableProgramGroupPage=yes 23 | OutputBaseFilename=blink-1.10.1-setup 24 | Compression=lzma 25 | SolidCompression=yes 26 | WizardStyle=modern 27 | 28 | [Languages] 29 | Name: "english"; MessagesFile: "compiler:Default.isl" 30 | Name: "armenian"; MessagesFile: "compiler:Languages\Armenian.isl" 31 | Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" 32 | Name: "bulgarian"; MessagesFile: "compiler:Languages\Bulgarian.isl" 33 | Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl" 34 | Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl" 35 | Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl" 36 | Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" 37 | Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" 38 | Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" 39 | Name: "french"; MessagesFile: "compiler:Languages\French.isl" 40 | Name: "german"; MessagesFile: "compiler:Languages\German.isl" 41 | Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" 42 | Name: "icelandic"; MessagesFile: "compiler:Languages\Icelandic.isl" 43 | Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" 44 | Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" 45 | Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" 46 | Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" 47 | Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" 48 | Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" 49 | Name: "slovak"; MessagesFile: "compiler:Languages\Slovak.isl" 50 | Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" 51 | Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" 52 | Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl" 53 | Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" 54 | 55 | [Tasks] 56 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" 57 | 58 | [Files] 59 | Source: "C:\BlinkDeploy\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs 60 | 61 | ; NOTE: Don't use "Flags: ignoreversion" on any shared system files 62 | 63 | [Icons] 64 | Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" 65 | Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon 66 | 67 | [Run] 68 | Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent 69 | 70 | -------------------------------------------------------------------------------- /Storage/CDbmStorageHandler.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Storage/CDbmStorageHandler.cpp -------------------------------------------------------------------------------- /Storage/CDbmStorageHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Storage/CDbmStorageHandler.h -------------------------------------------------------------------------------- /Storage/CXmlStorageHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include "CXmlStorageHandler.h" 8 | 9 | BYTE CXmlStorageHandler::loadFromFile(const QString& filename, QMap& projectMap) 10 | { 11 | QFile file(filename); 12 | 13 | if (!file.open(QIODevice::ReadOnly)) { 14 | return LoadFileError; 15 | } 16 | 17 | QDomDocument doc("ProjectML"); 18 | 19 | QString errMsg; 20 | int errLine, errCol; 21 | 22 | if (!doc.setContent(&file, false, &errMsg, &errLine, &errCol)) { 23 | qDebug() << "QDomDocument setContent() failed in CXmlStorageHandler::loadFromFile()!" << Qt::endl; 24 | qDebug() << "err:" << errMsg << ", line:" << errLine << " column:" << errCol << Qt::endl; 25 | file.close(); 26 | return LoadFileError; 27 | } 28 | 29 | file.close(); 30 | 31 | QDomElement docElement = doc.documentElement(); 32 | 33 | // start from doc first child 34 | QDomNode docNode = docElement.firstChild(); 35 | 36 | while (!docNode.isNull()) { 37 | QDomElement rootItem = docNode.toElement(); 38 | 39 | if (rootItem.tagName() == "project") { 40 | projectMap.clear(); 41 | QDomNode node = rootItem.firstChild(); 42 | 43 | while (!node.isNull()) { 44 | QDomElement element = node.toElement(); 45 | if (!element.isNull()) { 46 | if (element.tagName() == "projectItem") { 47 | CProjectItem item; 48 | 49 | fillProjectItem(item, element); 50 | projectMap[element.attribute("name", "")] = item; 51 | } 52 | node = node.nextSibling(); 53 | } 54 | } 55 | } 56 | docNode = docNode.nextSibling(); 57 | } 58 | 59 | return NoError; 60 | } 61 | 62 | QDomElement CXmlStorageHandler::createXMLNode(QDomDocument &document, const CProjectItem &projectItem) 63 | { 64 | QDomElement element = document.createElement("projectItem"); 65 | 66 | element.setAttribute("name", projectItem.name_); 67 | element.setAttribute("srcDir", projectItem.srcDir_); 68 | element.setAttribute("srcMask", projectItem.srcMask_); 69 | element.setAttribute("headerMask", projectItem.headerMask_); 70 | element.setAttribute("tagUpdateDateTime", projectItem.tagUpdateDateTime_); 71 | element.setAttribute("projectCreateDateTime", projectItem.projectCreateDateTime_); 72 | element.setAttribute("labels", projectItem.labels_); 73 | element.setAttribute("dirToExclude", projectItem.dirToExclude_); 74 | element.setAttribute("fileMaskToExclude", projectItem.fileMaskToExclude_); 75 | 76 | return element; 77 | } 78 | 79 | void CXmlStorageHandler::fillProjectItem(CProjectItem& projectItemToBeFill, const QDomElement& element) 80 | { 81 | QString name, srcDir, srcMask, headerMask; 82 | QString tagUpdateDateTime, projectCreateDateTime; 83 | QString labels, dirToExclude, fileMaskToExclude; 84 | 85 | name = element.attribute("name", ""); 86 | srcDir = element.attribute("srcDir", ""); 87 | srcMask = element.attribute("srcMask", ""); 88 | headerMask = element.attribute("headerMask", ""); 89 | labels = element.attribute("labels", ""); 90 | dirToExclude = element.attribute("dirToExclude", ""); 91 | fileMaskToExclude = element.attribute("fileMaskToExclude", ""); 92 | 93 | tagUpdateDateTime = element.attribute("tagUpdateDateTime", ""); 94 | projectCreateDateTime = element.attribute("projectCreateDateTime", ""); 95 | 96 | CProjectItem projectItem(name, srcDir, srcMask, headerMask, 97 | tagUpdateDateTime, projectCreateDateTime, labels, dirToExclude, fileMaskToExclude); 98 | 99 | projectItemToBeFill = projectItem; 100 | } 101 | 102 | BYTE CXmlStorageHandler::saveToFile(const QString& filename, const QMap& projectMap) 103 | { 104 | QDomDocument doc("ProjectML"); 105 | 106 | // record 107 | QDomElement recordRoot = doc.createElement("record"); 108 | doc.appendChild(recordRoot); 109 | 110 | // project 111 | QDomElement projectRoot = doc.createElement("project"); 112 | recordRoot.appendChild(projectRoot); 113 | 114 | CProjectItem projectItem; 115 | foreach (projectItem, projectMap) { 116 | QDomElement node = createXMLNode(doc, projectItem); 117 | projectRoot.appendChild(node); 118 | } 119 | 120 | #ifdef DEBUG_XML 121 | QDomElement element = doc.createElement("projectItem"); 122 | element.setAttribute("name", "a1"); 123 | element.setAttribute("srcDir", "a2"); 124 | element.setAttribute("srcMask", "a3"); 125 | element.setAttribute("headerMask", "a4"); 126 | element.setAttribute("labels", "a5"); 127 | root.appendChild(element); 128 | #endif 129 | 130 | QFile file(filename); 131 | if (!file.open(QIODevice::WriteOnly)) { 132 | //QMessageBox::warning(this, "Saving", "Failed to save file.", QMessageBox::Ok, QMessageBox::NoButton); /* <-- YCH modified 31/08/06, just for reference, to be removed */ 133 | return SaveFileError; 134 | } 135 | 136 | QTextStream ts(&file); 137 | ts << doc.toString(); 138 | file.close(); 139 | 140 | return NoError; 141 | } 142 | 143 | 144 | -------------------------------------------------------------------------------- /Storage/CXmlStorageHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef CXML_STORAGE_HANDLER_H 2 | #define CXML_STORAGE_HANDLER_H 3 | 4 | #include 5 | #include "Utils/commonType.h" 6 | #include "Model/CProjectItem.h" 7 | #include "IStorageHandler.h" 8 | 9 | class CXmlStorageHandler : IStorageHandler 10 | { 11 | public: 12 | enum FileError { 13 | NoError = 0, 14 | LoadFileError = 1, 15 | InvalidFileError = 2, 16 | SaveFileError = 3 17 | }; 18 | 19 | CXmlStorageHandler() {}; 20 | virtual ~CXmlStorageHandler() {}; 21 | 22 | BYTE loadFromFile(const QString& filename, QMap& projectMap); 23 | BYTE saveToFile(const QString& filename, const QMap& projectMap); 24 | 25 | private: 26 | QDomElement createXMLNode(QDomDocument& document, const CProjectItem& projectItem); 27 | 28 | void fillProjectItem(CProjectItem& projectItemToBeFill, const QDomElement& element); 29 | 30 | }; 31 | 32 | #endif // CXML_STORAGE_HANDLER_H 33 | 34 | -------------------------------------------------------------------------------- /Storage/IStorageHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef ISTORAGE_HANDLER_H 2 | #define ISTORAGE_HANDLER_H 3 | 4 | #include "Utils/commonType.h" 5 | 6 | // interface for storage handler 7 | 8 | class IStorageHandler { 9 | public: 10 | IStorageHandler() {}; 11 | virtual ~IStorageHandler() {}; 12 | 13 | virtual BYTE loadFromFile(const QString& filename, QMap& projectList) = 0; 14 | virtual BYTE saveToFile(const QString& filename, const QMap& projectList) = 0; 15 | }; 16 | 17 | #endif // ISTORAGE_HANDLER_H 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tool/linuxdeployqt-continuous-x86_64.AppImage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/Tool/linuxdeployqt-continuous-x86_64.AppImage -------------------------------------------------------------------------------- /Utils/CUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "CUtils.h" 2 | 3 | #include 4 | 5 | CUtils::CUtils() 6 | { 7 | 8 | } 9 | 10 | CUtils::~CUtils() 11 | { 12 | 13 | } 14 | 15 | // from John Suykerbuyk in lists.trolltech.com 16 | bool CUtils::removeDirectory(QDir &aDir) 17 | { 18 | bool has_err = false; 19 | if (aDir.exists()) 20 | { 21 | QFileInfoList entries = aDir.entryInfoList(QDir::NoDotAndDotDot | 22 | QDir::Dirs | QDir::Files); 23 | int count = entries.size(); 24 | for (int idx = 0; ((idx < count) && (!has_err)); idx++) 25 | { 26 | QFileInfo entryInfo = entries[idx]; 27 | QString path = entryInfo.absoluteFilePath(); 28 | if (entryInfo.isDir()) 29 | { 30 | QDir dirToRemove(path); 31 | has_err = CUtils::removeDirectory(dirToRemove); 32 | } 33 | else 34 | { 35 | QFile file(path); 36 | if (!file.remove()) 37 | has_err = true; 38 | } 39 | } 40 | if (!aDir.rmdir(aDir.absolutePath())) 41 | has_err = true; 42 | } 43 | return(has_err); 44 | } 45 | 46 | void CUtils::bufLog(unsigned char* buffer, long size) 47 | { 48 | long i; 49 | 50 | printf("size = %ld\n", size); 51 | for (i = 0; i < size; i++) { 52 | printf("%02X ", buffer[i]); 53 | if ((i != 0) && ((i+1) % 25 == 0)) { 54 | printf("\n"); 55 | } 56 | } 57 | printf("\n"); 58 | } 59 | 60 | QString CUtils::bufToQString(unsigned char* buffer, long size) 61 | { 62 | long i; 63 | QString result = QString(""); 64 | QString tmpStr; 65 | 66 | for (i = 0; i < size; i++) { 67 | tmpStr= QString("%1 ").arg(buffer[i], 2, 16, QLatin1Char('0')); // hex string 68 | result += tmpStr; 69 | } 70 | 71 | return result; 72 | } 73 | 74 | 75 | void CUtils::putByte(BYTE* buffer, BYTE in) 76 | { 77 | buffer[0] = in; 78 | } 79 | 80 | void CUtils::putWord(BYTE* buffer, WORD in) 81 | { 82 | buffer[0] = static_cast (in >> 8); 83 | buffer[1] = static_cast (in); 84 | } 85 | 86 | void CUtils::putDWord(BYTE* buffer, DWORD in) 87 | { 88 | buffer[0] = static_cast (in >> 24); 89 | buffer[1] = static_cast (in >> 16); 90 | buffer[2] = static_cast (in >> 8); 91 | buffer[3] = static_cast (in); 92 | } 93 | 94 | BYTE CUtils::getByte(BYTE* buffer) 95 | { 96 | BYTE out; 97 | out = static_cast (buffer[0]); 98 | return out; 99 | } 100 | 101 | WORD CUtils::getWord(BYTE* buffer) 102 | { 103 | WORD out; 104 | out = (static_cast (buffer[0]) << 8) + (static_cast (buffer[1])); 105 | return out; 106 | } 107 | 108 | DWORD CUtils::getDWord(BYTE* buffer) 109 | { 110 | DWORD out; 111 | out = (static_cast (buffer[0]) << 24) + (static_cast (buffer[1]) << 16) + 112 | (static_cast (buffer[2]) << 8) + (static_cast (buffer[3])); 113 | return out; 114 | } 115 | 116 | void CUtils::encode(BYTE *buffer, long& bufLen) 117 | { 118 | long updatedBufLen; 119 | static BYTE encodeDecodeBuf[ENCODE_DECODE_BUFFER_LEN]; 120 | 121 | encodeDWORDSeq((BYTE*) buffer, bufLen, encodeDecodeBuf, updatedBufLen); 122 | 123 | // copy back to buffer 124 | memset(buffer, 0, bufLen); 125 | memcpy(buffer, encodeDecodeBuf, updatedBufLen); 126 | 127 | // update buffer length 128 | bufLen = updatedBufLen; 129 | } 130 | 131 | void CUtils::decode(BYTE *buffer, long& bufLen) 132 | { 133 | long updatedBufLen; 134 | static BYTE encodeDecodeBuf[ENCODE_DECODE_BUFFER_LEN]; 135 | 136 | decodeDWORDSeq((BYTE*) buffer, bufLen, encodeDecodeBuf, updatedBufLen); 137 | 138 | // copy back to buffer 139 | memset(buffer, 0, bufLen); 140 | memcpy(buffer, encodeDecodeBuf, updatedBufLen); 141 | 142 | // update buffer length 143 | bufLen = updatedBufLen; 144 | } 145 | 146 | bool CUtils::encodeDWORDSeq(BYTE *inBuf, long inBufLen, BYTE* outBuf, long& outBufLen) 147 | { 148 | DWORD dwordExtracted; 149 | long inIdx = 0; 150 | long outIdx = 0; 151 | long dwordSize = sizeof(DWORD); 152 | 153 | BYTE encodedByte; 154 | WORD encodedWord; 155 | DWORD encodedDWord; 156 | 157 | if (inBufLen % dwordSize != 0) { 158 | return false; 159 | } 160 | 161 | outBufLen = 0; 162 | 163 | do { 164 | dwordExtracted = getDWord(&(inBuf[inIdx])); 165 | 166 | if (dwordExtracted <= ENCODE_USE_1_BYTE) { 167 | encodedByte = static_cast (dwordExtracted); 168 | encodedByte |= MASK_HEADER_BYTE; 169 | putByte(&(outBuf[outIdx]), encodedByte); 170 | outIdx += 1; 171 | outBufLen += 1; 172 | } else if (dwordExtracted <= ENCODE_USE_2_BYTE) { 173 | encodedWord = static_cast (dwordExtracted); 174 | encodedWord |= MASK_HEADER_WORD; 175 | putWord(&(outBuf[outIdx]), encodedWord); 176 | outIdx += 2; 177 | outBufLen += 2; 178 | } else if (dwordExtracted <= ENCODE_USE_4_BYTE) { 179 | encodedDWord = static_cast (dwordExtracted); 180 | encodedDWord |= MASK_HEADER_DWORD; 181 | putDWord(&(outBuf[outIdx]), encodedDWord); 182 | outIdx += 4; 183 | outBufLen += 4; 184 | } 185 | inIdx += dwordSize; 186 | 187 | } while (inIdx < inBufLen); 188 | return true; 189 | } 190 | 191 | bool CUtils::decodeDWORDSeq(BYTE *inBuf, long inBufLen, BYTE* outBuf, long& outBufLen) 192 | { 193 | long inIdx = 0; 194 | long outIdx = 0; 195 | 196 | BYTE byteExtracted; 197 | 198 | BYTE decodedByte; 199 | WORD decodedWord; 200 | DWORD decodedDWord; 201 | 202 | outBufLen = 0; 203 | 204 | do { 205 | byteExtracted = getByte(&(inBuf[inIdx])); 206 | 207 | if ((byteExtracted & HEADER_BIT_1_MASK) == 0) { // 1 byte length 208 | decodedByte = getByte(&(inBuf[inIdx])) & MASK_WITHOUT_HEADER_BYTE; 209 | putDWord(&(outBuf[outIdx]), static_cast (decodedByte)); 210 | inIdx += 1; 211 | } else if ((byteExtracted & HEADER_BIT_2_MASK) == 0) { // 2 byte length 212 | decodedWord = getWord(&(inBuf[inIdx])) & MASK_WITHOUT_HEADER_WORD; 213 | putDWord(&(outBuf[outIdx]), static_cast (decodedWord)); 214 | inIdx += 2; 215 | } else { // 4 byte length 216 | decodedDWord = getDWord(&(inBuf[inIdx])) & MASK_WITHOUT_HEADER_DWORD; 217 | putDWord(&(outBuf[outIdx]), static_cast (decodedDWord)); 218 | inIdx += 4; 219 | } 220 | outIdx += 4; 221 | outBufLen += 4; 222 | 223 | } while (inIdx < inBufLen); 224 | 225 | return true; 226 | 227 | 228 | } 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /Utils/CUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef CUITLS_H 2 | #define CUITLS_H 3 | 4 | #include 5 | #include 6 | 7 | #include "commonType.h" 8 | 9 | class CUtils 10 | { 11 | public: 12 | CUtils(); 13 | ~CUtils(); 14 | 15 | // recursively remove a directory 16 | static bool removeDirectory(QDir &aDir); 17 | 18 | static void bufLog(unsigned char* buffer, long size); 19 | static QString bufToQString(unsigned char* buffer, long size); 20 | 21 | // for convenient use 22 | static void encode(BYTE *buffer, long& bufLen); 23 | static void decode(BYTE *buffer, long& bufLen); 24 | 25 | // max allowed bit for each long here is 30, as using 2 bit for header 26 | // note: big endian is expected, be careful of little endian 27 | static bool encodeDWORDSeq(BYTE *inBuf, long inBufLen, BYTE* outBuf, long& outBufLen); 28 | static bool decodeDWORDSeq(BYTE *inBuf, long inBufLen, BYTE* outBuf, long& outBufLen); 29 | 30 | static void putByte(BYTE* buffer, BYTE in); 31 | static void putWord(BYTE* buffer, WORD in); 32 | static void putDWord(BYTE* buffer, DWORD in); 33 | 34 | static BYTE getByte(BYTE* buffer); 35 | static WORD getWord(BYTE* buffer); 36 | static DWORD getDWord(BYTE* buffer); 37 | 38 | private: 39 | 40 | // for encode 41 | static const DWORD ENCODE_USE_1_BYTE = 0x7F; // 01111111 42 | static const DWORD ENCODE_USE_2_BYTE = 0x3FFF; // 00111111 11111111 43 | static const DWORD ENCODE_USE_4_BYTE = 0x3FFFFFFF; // 00111111 11111111 11111111 11111111 44 | 45 | static const BYTE MASK_HEADER_BYTE = 0x00; // 00 i.e. 00000000 46 | static const WORD MASK_HEADER_WORD = 0x8000; // 10 i.e. 10000000 00000000 47 | static const DWORD MASK_HEADER_DWORD = 0xC0000000; // 11 i.e. 11000000 00000000 00000000 00000000 48 | 49 | // for decode 50 | static const BYTE HEADER_BIT_1_MASK = 0x80; // 10000000 51 | static const BYTE HEADER_BIT_2_MASK = 0x40; // 01000000 52 | 53 | static const BYTE MASK_WITHOUT_HEADER_BYTE = 0x7F; // 01111111 54 | static const WORD MASK_WITHOUT_HEADER_WORD = 0x3FFF; // 00111111 11111111 55 | static const DWORD MASK_WITHOUT_HEADER_DWORD = 0x3FFFFFFF; // 00111111 11111111 11111111 11111111 56 | 57 | static const long ENCODE_DECODE_BUFFER_LEN = 5000; 58 | 59 | 60 | }; 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /Utils/commonType.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_TYPE_H 2 | #define COMMON_TYPE_H 3 | 4 | typedef unsigned char BYTE; 5 | typedef unsigned short WORD; 6 | typedef unsigned long DWORD; 7 | 8 | enum enuTRACE_LEVEL_ {TRACE_DEBUG, TRACE_INFO, TRACE_WARNING, TRACE_ERROR}; 9 | typedef enum enuTRACE_LEVEL_ TRACE_LEVEL; 10 | 11 | #endif // COMMON_TYPE_H 12 | -------------------------------------------------------------------------------- /Utils/plugins/dbmplugin/dbmplugin.cpp: -------------------------------------------------------------------------------- 1 | static int nextId = 0; // zero represents an invalid ID 2 | 3 | 4 | DbmInterfacePlugin::~DbmInterfacePlugin() 5 | { 6 | QMapIterator i(dbptrs); 7 | while (i.hasNext()) { 8 | i.next(); 9 | close(i.key()); 10 | } 11 | } 12 | 13 | 14 | Q_EXPORT_PLUGIN(DbmPlugin, DbmInterfacePlugin) 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Utils/plugins/dbmplugin/dbmplugin.h: -------------------------------------------------------------------------------- 1 | #ifndef DBMPLUGIN_H 2 | #define DBMPLUGIN_H 3 | 4 | class Info 5 | { 6 | public: 7 | Info(void *_db=0, const QString &_dbmName=QString()) 8 | : db(_db), dbmName(_dbmName) {} 9 | 10 | void *db; 11 | QString dbmName; 12 | }; 13 | 14 | class DbmInterfacePlugin : public QObject, 15 | public DbmInterface 16 | { 17 | Q_OBJECT 18 | Q_INTERFACES(DbmInterface) 19 | 20 | public: 21 | ~DbmInterfacePlugin(); 22 | 23 | int open(const QString &filename); 24 | void close(int id); 25 | QStringList lookup(int id, const QString &key); 26 | 27 | private: 28 | QMap dbptrs; 29 | }; 30 | 31 | 32 | #endif 33 | 34 | -------------------------------------------------------------------------------- /Utils/plugins/dbmplugin/dbmplugin.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += plugin 3 | #LIBS += -ldb_cxx -ldb -lgdbm 4 | LIBS += -ldb47 5 | INCLUDEPATH += ../external 6 | #DESTDIR = ../plugins 7 | HEADERS = dbmplugin.h 8 | SOURCES = dbmplugin.cpp 9 | 10 | -------------------------------------------------------------------------------- /Utils/qTag/interfaces.h: -------------------------------------------------------------------------------- 1 | class DbmInterface 2 | { 3 | public: 4 | virtual ~DbmInterface() {} 5 | virtual int open(const QString &filename) = 0; 6 | virtual void close(int id) = 0; 7 | virtual QStringList lookup(int id, const QString &key) = 0; 8 | }; 9 | 10 | Q_DECLARE_INTERFACE(DbmInterface, "projectloader.DbmInterface/1.0") 11 | 12 | -------------------------------------------------------------------------------- /Utils/qTag/keyword.txt: -------------------------------------------------------------------------------- 1 | goto break return continue asm 2 | case default 3 | if else switch 4 | while for do 5 | sizeof 6 | int long short char void 7 | signed unsigned float double 8 | struct union enum typedef 9 | static register auto volatile extern const 10 | 11 | new delete this friend using 12 | public protected private 13 | inline virtual explicit export bool wchar_t 14 | throw try catch 15 | operator typeid 16 | and bitor or xor compl bitand and_eq or_eq xor_eq not not_eq 17 | const_cast 18 | static_cast 19 | dynamic_cast 20 | reinterpret_cast 21 | mutable 22 | class 23 | typename 24 | template 25 | namespace 26 | NPOS 27 | true 28 | false 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Utils/qTag/pyclean.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # History 4 | # Version Date Creator Remarks 5 | # 1.0 14 Feb 08 YCH Initial version 6 | 7 | import glob 8 | import os 9 | 10 | import string 11 | import getopt, sys 12 | 13 | removeMaskOptionList = ['makefile', 'debug', 'release'] 14 | 15 | removeMaskListDict = dict() 16 | 17 | removeMaskListDict['release'] = [ 18 | "release/*.ii", 19 | "release/*.o", 20 | "release/moc*.cpp", 21 | "release/*.exe", 22 | "release/qrc*.cpp", 23 | "ui_*.h" 24 | ] 25 | 26 | removeMaskListDict['debug'] = [ 27 | "debug\*.ii", 28 | "debug\*.o", 29 | "debug\moc*.cpp", 30 | "debug\*.exe", 31 | "debug\qrc*.cpp", 32 | "ui_*.h" 33 | ] 34 | 35 | removeMaskListDict['makefile'] = [ 36 | "*.o", 37 | "Makefile*.*", 38 | "Makefile*", 39 | "*.Debug", 40 | "*.Release", 41 | ] 42 | 43 | def usage(): 44 | print "pyclean" 45 | print "Usage [--all] [--makefile] [--debug] [--release]" 46 | print "" 47 | 48 | def main(): 49 | 50 | bClean = dict() 51 | for removeMaskOption in removeMaskOptionList: 52 | bClean[removeMaskOption] = False # False initially 53 | 54 | shortOptionStr = "" 55 | longOptionList = removeMaskOptionList + ["all"] 56 | 57 | try: 58 | optArgList, argList = getopt.getopt(sys.argv[1:], shortOptionStr, longOptionList) 59 | except getopt.GetoptError, err: 60 | print str(err) 61 | usage() 62 | sys.exit(2) 63 | 64 | if len(optArgList) == 0: 65 | usage() 66 | sys.exit(2) 67 | 68 | for opt, arg in optArgList: 69 | bValidOpt = False 70 | for removeMaskOption in removeMaskOptionList: 71 | if opt == "--" + removeMaskOption: 72 | bClean[removeMaskOption] = True 73 | bValidOpt = True 74 | if opt == "--" + "all": 75 | for removeMaskOption in removeMaskOptionList: 76 | bClean[removeMaskOption] = True 77 | bValidOpt = True 78 | 79 | if bValidOpt == False: 80 | assert False, "unhandled option" 81 | 82 | for removeMaskOption in removeMaskOptionList: 83 | if bClean[removeMaskOption] == True: 84 | print removeMaskOption + ":" 85 | print 86 | currentRemoveMaskList = removeMaskListDict[removeMaskOption] 87 | 88 | for removeMask in currentRemoveMaskList: 89 | globList = glob.glob(removeMask) 90 | for globItem in globList: 91 | print "removing " + globItem + "..." 92 | os.remove(globItem) 93 | 94 | 95 | if __name__ == "__main__": 96 | main() 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Utils/qTag/qTag.cpp: -------------------------------------------------------------------------------- 1 | /* vim: set fdm=marker : */ 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include // for getopt 15 | 16 | #include 17 | 18 | #include "qTagApp.h" 19 | #include "qTagger.h" 20 | 21 | #include "CUtils.h" 22 | 23 | #include "CTagResultItem.h" 24 | 25 | using namespace std; 26 | 27 | int main(int argc, char *argv[]) 28 | { 29 | QTagApplication app(argc, argv); 30 | QTagger tagger; 31 | QString tagToQuery; 32 | 33 | QString inputFileName(QTagger::kQTAG_DEFAULT_INPUTLIST_FILE); // default input file name 34 | QString tagDbFileName(QTagger::kQTAG_DEFAULT_TAGDBNAME); // default tag database file name 35 | QString configFileName(QTagger::kQTAG_CONFIG_FILE); 36 | 37 | Qt::CaseSensitivity caseSensitive; 38 | 39 | bool cFlag = false; // create tag 40 | bool qFlag = false; // query tag 41 | bool tFlag = false; 42 | bool iFlag = false; // default to false, i.e. case sensitive in query 43 | bool dFlag = false; // debug flag 44 | bool lFlag = false; // input file 45 | 46 | char *qValue = NULL; 47 | char *tValue = NULL; 48 | char *lValue = NULL; 49 | 50 | int cOpt; 51 | 52 | while ((cOpt = getopt(argc, argv, "cq:t:i:d:l")) != -1) { 53 | switch (cOpt) 54 | { 55 | case 'c': 56 | cFlag = true; 57 | break; 58 | case 'q': 59 | qFlag = true; 60 | qValue = optarg; 61 | break; 62 | case 't': 63 | tFlag = true; 64 | tValue = optarg; 65 | break; 66 | case 'i': 67 | iFlag = true; 68 | break; 69 | case 'd': 70 | dFlag = true; 71 | break; 72 | case 'l': 73 | lFlag = true; 74 | lValue = optarg; 75 | break; 76 | 77 | case '?': 78 | if ((optopt == 'q') || (optopt == 't') || (optopt == 'l')) { 79 | fprintf (stderr, "Option -%c requires an argument.\n", optopt); 80 | } else if (isprint(optopt)) { 81 | fprintf (stderr, "Unknown option `-%c'.\n", optopt); 82 | } else { 83 | fprintf (stderr, 84 | "Unknown option character `\\x%x'.\n", 85 | optopt); 86 | } 87 | } 88 | } 89 | 90 | // Case Sensitivity 91 | if (iFlag) { 92 | caseSensitive = Qt::CaseInsensitive; 93 | } else { 94 | caseSensitive = Qt::CaseSensitive; 95 | } 96 | 97 | // handling of input file 98 | if (lFlag) { 99 | inputFileName = lValue; 100 | } 101 | 102 | // handling of tag database file 103 | if (tFlag) { 104 | tagDbFileName = tValue; 105 | } 106 | 107 | if (cFlag) { // remove existing env and db files first 108 | QElapsedTimer timer; 109 | timer.start(); 110 | 111 | T_FileItemList fileList; 112 | 113 | CSourceFileList::loadFileList(inputFileName, fileList); 114 | 115 | qDebug() << "Processing File..." << Qt::endl; 116 | 117 | tagger.createTag(fileList); 118 | tagger.writeTagDb(tagDbFileName); 119 | 120 | qDebug() << "Operation took" << QString::number(((double) timer.elapsed() / 1000), 'f', 3) << "s" << Qt::endl; 121 | } 122 | 123 | // handling of tag to be query 124 | if (qFlag) { 125 | // read currently load project 126 | 127 | qDebug() << "applicationDirPath() A IN" << Qt::endl; 128 | qDebug() << "QCoreApplication::applicationDirPath() = " << QCoreApplication::applicationDirPath() << Qt::endl; 129 | QFile qTagConfigFile(QCoreApplication::applicationDirPath() + "/" + configFileName); 130 | qDebug() << "applicationDirPath() A OUT" << Qt::endl; 131 | 132 | if (!qTagConfigFile.open(QIODevice::ReadOnly | QIODevice::Text)) { 133 | qDebug() << "Cannot open config file (" << configFileName << ") for reading!" << Qt::endl; 134 | return -1; 135 | } 136 | 137 | QTextStream qTagConfigFileIn(&qTagConfigFile); 138 | 139 | QString configStr; 140 | QString projectLoadStr = "projectLoad="; 141 | 142 | while (!qTagConfigFileIn.atEnd()) { 143 | configStr = qTagConfigFileIn.readLine(); 144 | if (configStr.startsWith(projectLoadStr)) { 145 | configStr.remove(0, projectLoadStr.length()); 146 | 147 | qDebug() << "applicationDirPath() B IN" << Qt::endl; 148 | qDebug() << "QCoreApplication::applicationDirPath() = " << QCoreApplication::applicationDirPath() << Qt::endl; 149 | tagDbFileName = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tags/" + configStr + "/" + tagDbFileName; 150 | qDebug() << "applicationDirPath() B OUT" << Qt::endl; 151 | 152 | qDebug() << "applicationDirPath() C IN" << Qt::endl; 153 | qDebug() << "QCoreApplication::applicationDirPath() = " << QCoreApplication::applicationDirPath() << Qt::endl; 154 | inputFileName = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tags/" + configStr + "/" + inputFileName; 155 | qDebug() << "applicationDirPath() C OUT" << Qt::endl; 156 | 157 | break; 158 | } 159 | } 160 | 161 | qTagConfigFile.close(); 162 | 163 | // start query 164 | tagToQuery = QString(qValue); 165 | 166 | QList resultList; 167 | QString tagToQueryFiltered; 168 | 169 | tagger.queryTag(inputFileName, tagDbFileName, tagToQuery, tagToQueryFiltered, resultList, caseSensitive); 170 | 171 | foreach (const CTagResultItem& result, resultList) { 172 | //cout << "[" << result.functionSignature_.toStdString() << "]" << Qt::endl; 173 | cout << result << Qt::endl; 174 | } 175 | } 176 | 177 | return 0; 178 | } 179 | 180 | 181 | -------------------------------------------------------------------------------- /Utils/qTag/qTag.pro: -------------------------------------------------------------------------------- 1 | #QMAKE_CC = gcc 2 | QMAKE_CXX = g++ 3 | 4 | TEMPLATE = app 5 | 6 | #QT = core 7 | QT -= gui 8 | 9 | CONFIG += console warn_on 10 | LIBS += -L"../external" 11 | INCLUDEPATH += "../" 12 | INCLUDEPATH += "../../Model/qTagger/" 13 | 14 | SOURCES += qTag.cpp \ 15 | qTagApp.cpp \ 16 | ../../Model/qTagger/CTagResultItem.cpp \ 17 | ../../Model/qTagger/qTagger.cpp \ 18 | ../../Model/COutputItem.cpp \ 19 | ../../Model/qTagger/CSourceFileList.cpp \ 20 | ../CUtils.cpp \ 21 | 22 | HEADERS += qTagApp.h \ 23 | ../../Model/qTagger/CTagResultItem.h \ 24 | ../../Model/qTagger/qTagger.h \ 25 | ../../Model/COutputItem.h \ 26 | ../../Model/qTagger/CSourceFileList.h \ 27 | ../CUtils.h \ 28 | 29 | 30 | -------------------------------------------------------------------------------- /Utils/qTag/qTagApp.cpp: -------------------------------------------------------------------------------- 1 | #include "qTagApp.h" 2 | 3 | 4 | QTagApplication::QTagApplication(int& argc, char**& argv) 5 | : QCoreApplication(argc, argv) 6 | { 7 | 8 | 9 | } 10 | 11 | QTagApplication::~QTagApplication() 12 | { 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Utils/qTag/qTagApp.h: -------------------------------------------------------------------------------- 1 | #ifndef QTAGAPP_H 2 | #define QTAGAPP_H 3 | 4 | #include 5 | 6 | class QTagApplication : public QCoreApplication 7 | { 8 | Q_OBJECT 9 | public: 10 | QTagApplication(int& argc, char**& argv); 11 | 12 | virtual ~QTagApplication(); 13 | 14 | 15 | }; 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Utils/qTag/test/TestCRecordPool.cpp: -------------------------------------------------------------------------------- 1 | #include "TestCRecordPool.h" 2 | 3 | void TestCRecordPool::initTestCase() 4 | { 5 | record_ = new CRecord("test", 1); 6 | recordItem_ = new CRecordItem(1); 7 | record_->addItem(recordItem_); 8 | } 9 | 10 | void TestCRecordPool::compress() 11 | { 12 | unsigned char buffer[5000]; 13 | unsigned char testData1[] = {0, 1}; 14 | long bufLen; 15 | long maxBufferLen = 5000; 16 | 17 | QVERIFY(record_ != 0); 18 | record_->packBuffer(static_cast (buffer), bufLen, 5000); 19 | QCOMPARE(buffer, testData1); 20 | 21 | } 22 | 23 | void TestCRecordPool::cleanupTestCase() 24 | { 25 | delete record_; 26 | record_ = 0; 27 | } 28 | 29 | QTEST_MAIN(TestCRecordPool) 30 | 31 | 32 | -------------------------------------------------------------------------------- /Utils/qTag/test/TestCRecordPool.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTCRECORDPOOL_H 2 | 3 | #define TESTCRECORDPOOL_H 4 | #include 5 | #include "CRecordPool.h" 6 | 7 | class TestCRecordPool: public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | TestCRecordPool() {}; 12 | ~TestCRecordPool() {}; 13 | private slots: 14 | void initTestCase(); 15 | void compress(); 16 | void cleanupTestCase(); 17 | 18 | private: 19 | CRecord* record_; 20 | CRecordItem* recordItem_; 21 | 22 | }; 23 | 24 | #endif // TESTCRECORDPOOL_H 25 | 26 | -------------------------------------------------------------------------------- /Utils/qTag/test/TestCRecordPool.pro: -------------------------------------------------------------------------------- 1 | #QMAKE_CC = gcc 2 | QMAKE_CXX = g++ 3 | 4 | #TEMPLATE = app 5 | 6 | QT -= gui 7 | 8 | CONFIG += console warn_on qtestlib 9 | INCLUDEPATH += "../" "../../" 10 | 11 | SOURCES += TestCRecordPool.cpp \ 12 | ../CRecordPool.cpp \ 13 | ../../CUtils.cpp \ 14 | 15 | HEADERS += TestCRecordPool.h \ 16 | ../CRecordPool.h \ 17 | ../../CUtils.h \ 18 | 19 | 20 | -------------------------------------------------------------------------------- /Utils/test/TestCUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "TestCUtils.h" 2 | 3 | void TestCUtils::initTestCase() 4 | { 5 | qRegisterMetaType ("BYTE_VECTOR"); 6 | 7 | } 8 | 9 | void TestCUtils::encode_data() 10 | { 11 | QTest::addColumn("inBuf"); 12 | QTest::addColumn("expectedBuf"); 13 | 14 | BYTE_VECTOR bufInput, bufExpected; 15 | 16 | bufInput.clear(); bufExpected.clear(); 17 | bufInput << 0x00 << 0x00 << 0x00 << 0x01; 18 | bufExpected << 0x01; 19 | QTest::newRow("encodeToByte") << bufInput << bufExpected; 20 | 21 | bufInput.clear(); bufExpected.clear(); 22 | bufInput << 0x00 << 0x00 << 0x00 << 0x7F; 23 | bufExpected << 0x7F; 24 | QTest::newRow("encodeToByteBoundary") << bufInput << bufExpected; 25 | 26 | bufInput.clear(); bufExpected.clear(); 27 | bufInput << 0x00 << 0x00 << 0x00 << 0x80; 28 | bufExpected << 0x80 << 0x80; 29 | QTest::newRow("encodeToWord") << bufInput << bufExpected; 30 | 31 | bufInput.clear(); bufExpected.clear(); 32 | bufInput << 0x00 << 0x00 << 0x3F << 0xFF; 33 | bufExpected << 0xBF << 0xFF; 34 | QTest::newRow("encodeToWordBoundary") << bufInput << bufExpected; 35 | 36 | bufInput.clear(); bufExpected.clear(); 37 | bufInput << 0x00 << 0x00 << 0x40 << 0x00; 38 | bufExpected << 0xC0 << 0x00 << 0x40 << 0x00; 39 | QTest::newRow("encodeToDWord") << bufInput << bufExpected; 40 | 41 | bufInput.clear(); bufExpected.clear(); 42 | bufInput << 0x3F << 0xFF << 0xFF << 0xFF; 43 | bufExpected << 0xFF << 0xFF << 0xFF << 0xFF; 44 | QTest::newRow("encodeToDWordBoundary") << bufInput << bufExpected; 45 | 46 | bufInput.clear(); bufExpected.clear(); 47 | bufInput << 0x00 << 0x00 << 0x00 << 0x7F << 0x00 << 0x00 << 0x00 << 0x80; 48 | bufExpected << 0x7F << 0x80 << 0x80; 49 | QTest::newRow("encodeToByteWord") << bufInput << bufExpected; 50 | 51 | // due to stored as little endian, commented by default 52 | //bufInput.clear(); bufExpected.clear(); 53 | //bufInput << 0x40 << 0x00 << 0x00 << 0x00 << 0x6D << 0x00 << 0x00 << 0x00; 54 | //bufExpected << 0xFF; 55 | //QTest::newRow("encodeErrRunTimeReturnSizeZero") << bufInput << bufExpected; 56 | 57 | } 58 | 59 | void TestCUtils::encode() 60 | { 61 | QFETCH(BYTE_VECTOR, inBuf); 62 | QFETCH(BYTE_VECTOR, expectedBuf); 63 | 64 | BYTE inBufByte[BUFLEN]; 65 | BYTE outBufByte[BUFLEN]; 66 | BYTE expectedBufByte[BUFLEN]; 67 | 68 | long outBufLen; 69 | int i; 70 | 71 | // input, output 72 | for (i = 0; i < inBuf.size(); ++i) { 73 | inBufByte[i] = inBuf[i]; 74 | } 75 | CUtils::encodeDWORDSeq(inBufByte, inBuf.size(), outBufByte, outBufLen); 76 | 77 | // expected, expected length 78 | QCOMPARE(outBufLen, static_cast (expectedBuf.size())); 79 | 80 | for (i = 0; i < expectedBuf.size(); ++i) { 81 | expectedBufByte[i] = expectedBuf[i]; 82 | } 83 | 84 | // comparision 85 | QString outStr = CUtils::bufToQString(outBufByte, outBufLen);; 86 | QString expectedStr = CUtils::bufToQString(expectedBufByte, outBufLen); 87 | 88 | QCOMPARE(outStr, expectedStr); 89 | } 90 | 91 | void TestCUtils::decode_data() 92 | { 93 | QTest::addColumn("inBuf"); 94 | QTest::addColumn("expectedBuf"); 95 | 96 | BYTE_VECTOR bufInput, bufExpected; 97 | 98 | bufInput.clear(); bufExpected.clear(); 99 | bufInput << 0x01; 100 | bufExpected << 0x00 << 0x00 << 0x00 << 0x01; 101 | QTest::newRow("decodeFromByte") << bufInput << bufExpected; 102 | 103 | bufInput.clear(); bufExpected.clear(); 104 | bufInput << 0x7F; 105 | bufExpected << 0x00 << 0x00 << 0x00 << 0x7F; 106 | QTest::newRow("decodeFromByteBoundary") << bufInput << bufExpected; 107 | 108 | bufInput.clear(); bufExpected.clear(); 109 | bufInput << 0x80 << 0x80; 110 | bufExpected << 0x00 << 0x00 << 0x00 << 0x80; 111 | QTest::newRow("decodeFromWord") << bufInput << bufExpected; 112 | 113 | bufInput.clear(); bufExpected.clear(); 114 | bufInput << 0xBF << 0xFF; 115 | bufExpected << 0x00 << 0x00 << 0x3F << 0xFF; 116 | QTest::newRow("decodeFromWordBoundary") << bufInput << bufExpected; 117 | 118 | bufInput.clear(); bufExpected.clear(); 119 | bufInput << 0xC0 << 0x00 << 0x40 << 0x00; 120 | bufExpected << 0x00 << 0x00 << 0x40 << 0x00; 121 | QTest::newRow("decodeFromDWord") << bufInput << bufExpected; 122 | 123 | bufInput.clear(); bufExpected.clear(); 124 | bufInput << 0xFF << 0xFF << 0xFF << 0xFF; 125 | bufExpected << 0x3F << 0xFF << 0xFF << 0xFF; 126 | QTest::newRow("decodeFromDWordBoundary") << bufInput << bufExpected; 127 | 128 | bufInput.clear(); bufExpected.clear(); 129 | bufInput << 0x7F << 0x80 << 0x80; 130 | bufExpected << 0x00 << 0x00 << 0x00 << 0x7F << 0x00 << 0x00 << 0x00 << 0x80; 131 | QTest::newRow("decodeFromByteWord") << bufInput << bufExpected; 132 | } 133 | 134 | void TestCUtils::decode() 135 | { 136 | QFETCH(BYTE_VECTOR, inBuf); 137 | QFETCH(BYTE_VECTOR, expectedBuf); 138 | 139 | BYTE inBufByte[BUFLEN]; 140 | BYTE outBufByte[BUFLEN]; 141 | BYTE expectedBufByte[BUFLEN]; 142 | 143 | long outBufLen; 144 | int i; 145 | 146 | // input, output 147 | for (i = 0; i < inBuf.size(); ++i) { 148 | inBufByte[i] = inBuf[i]; 149 | } 150 | CUtils::decodeDWORDSeq(inBufByte, inBuf.size(), outBufByte, outBufLen); 151 | 152 | // expected, expected length 153 | QCOMPARE(outBufLen, static_cast (expectedBuf.size())); 154 | 155 | for (i = 0; i < expectedBuf.size(); ++i) { 156 | expectedBufByte[i] = expectedBuf[i]; 157 | } 158 | 159 | // comparision 160 | QString outStr = CUtils::bufToQString(outBufByte, outBufLen);; 161 | QString expectedStr = CUtils::bufToQString(expectedBufByte, outBufLen); 162 | 163 | QCOMPARE(outStr, expectedStr); 164 | } 165 | 166 | void TestCUtils::cleanupTestCase() 167 | { 168 | } 169 | 170 | QTEST_MAIN(TestCUtils) 171 | 172 | 173 | -------------------------------------------------------------------------------- /Utils/test/TestCUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTCUTILS_H 2 | 3 | #define TESTCUTILS_H 4 | #include 5 | #include "CUtils.h" 6 | 7 | typedef QVector BYTE_VECTOR; 8 | 9 | class TestCUtils: public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | TestCUtils() {}; 14 | ~TestCUtils() {}; 15 | private slots: 16 | void initTestCase(); 17 | void encode_data(); 18 | void encode(); 19 | 20 | void decode_data(); 21 | void decode(); 22 | void cleanupTestCase(); 23 | 24 | private: 25 | static const long BUFLEN = 5000; 26 | 27 | }; 28 | 29 | Q_DECLARE_METATYPE(BYTE_VECTOR) 30 | 31 | #endif // TESTCUTILS_H 32 | 33 | -------------------------------------------------------------------------------- /Utils/test/TestCUtils.pro: -------------------------------------------------------------------------------- 1 | #QMAKE_CC = gcc 2 | QMAKE_CXX = g++ 3 | 4 | TEMPLATE = app 5 | 6 | QT -= gui 7 | 8 | CONFIG += console warn_on qtestlib 9 | INCLUDEPATH += "../" 10 | 11 | SOURCES += TestCUtils.cpp \ 12 | ../CUtils.cpp \ 13 | 14 | HEADERS += TestCUtils.h \ 15 | ../CUtils.h \ 16 | 17 | -------------------------------------------------------------------------------- /app/share/metainfo/io.github.ychclone.blink.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.github.ychclone.blink 4 | Blink code search 5 | GUI of live indexed grep for source code. Fuzzy suggestion in autocomplete. Files locator, search and replace. Switch different projects and start searching. 6 | 7 | 10 | 11 | GPL-3.0-or-later 12 | GPL-3.0-or-later 13 | https://github.com/ychclone/blink 14 | 15 | 16 | https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_codesearch.png 17 | Code search 18 | 19 | 20 | https://raw.githubusercontent.com/ychclone/blink/master/Screenshot/blink_filelisting.png 21 | File Listing 22 | 23 | 24 | 25 | 26 | io.github.ychclone.blink.png 27 | 128 28 | 29 | 32 | 33 | 34 | 35 | Utility 36 | 37 | 38 | code search 39 | blink code search 40 | app 41 | 42 | 43 | application/x-example 44 | 45 | io.github.ychclone.blink.desktop 46 | 47 | 48 | 51 | 52 | 53 | ychclone 54 | ychclone@gmail.com 55 | KDE 56 | 57 | none 58 | mild 59 | none 60 | none 61 | none 62 | none 63 | none 64 | 65 | 66 | 67 | Blink code search 68 | GUI of live indexed grep for source code. Fuzzy suggestion in autocomplete. Files locator, search and replace. Switch different projects and start searching. 69 | 70 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/share/metainfo/io.github.ychclone.blink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/app/share/metainfo/io.github.ychclone.blink.png -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - set QTDIR=C:\Qt\5.13.2\mingw73_32 3 | - set PATH=%PATH%;%QTDIR%\bin;C:\MinGW\bin 4 | build_script: 5 | - qmake blink.pro 6 | - mingw32-make 7 | 8 | -------------------------------------------------------------------------------- /blink.ini: -------------------------------------------------------------------------------- 1 | [Editor] 2 | geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\x92\0\0\0\x1b\0\0\x5\n\0\0\x2\xd8\0\0\0\x92\0\0\0G\0\0\x5\n\0\0\x2\xd8\0\0\0\0\0\0\0\0\x6@\0\0\0\x92\0\0\0G\0\0\x5\n\0\0\x2\xd8) 3 | 4 | [Setting] 5 | DefaultEditor= 6 | EditorFont="Ubuntu,23,-1,5,50,0,0,0,0,0" 7 | FileFilterCaseSensitive=false 8 | ProjectFont="Ubuntu,23,-1,5,50,0,0,0,0,0" 9 | SymbolFont="Ubuntu,18,-1,5,50,0,0,0,0,0" 10 | SymbolSearchCaseSensitive=false 11 | SymbolSearchRegularExpression=false 12 | TagDir=tags 13 | TimeoutRunExtProgram= 14 | TmpDir= 15 | UseExternalEditor=false 16 | ViewFilePanel=true 17 | ViewProjectPanel=true 18 | ViewToolbar=true 19 | actionProjectAndGroupCaseSensitive=false 20 | defaultMaskForNewProject=*.cpp *.c *.h *.hpp *.go *.java *.js *.py *.scala *.ts *.v *.vh *.sv *.svh *.yaml *.xml 21 | 22 | [Window] 23 | fileTabIndex=0 24 | geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\x94\0\0\0^\0\0\x5\xac\0\0\x3\x1a\0\0\0\x94\0\0\0\x8a\0\0\x5\xac\0\0\x3\x1a\0\0\0\0\0\0\0\0\x6@\0\0\0\x94\0\0\0\x8a\0\0\x5\xac\0\0\x3\x1a) 25 | projectTabIndex=0 26 | splitter="312 983 " 27 | -------------------------------------------------------------------------------- /blink.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | #CONFIG += release 3 | 4 | CONFIG += qscintilla2 5 | 6 | #QMAKE_CXXFLAGS += -g -fno-omit-frame-pointer 7 | 8 | QT += widgets xml network 9 | RC_FILE = Resources/Icons/appIcons.rc 10 | RESOURCES = Resources/app.qrc 11 | #RESOURCES += Resources/webview.qrc 12 | 13 | INCLUDEPATH += "Utils" 14 | INCLUDEPATH += "/opt/QScintilla_src-2.14.1/src" 15 | 16 | #LIBS += -LC:/QScintilla_src-2.14.1/src/release -llibqscintilla2_qt6 17 | #LIBS += -LC:/QScintilla_src-2.14.1/src/debug -llibqscintilla2_qt6d 18 | 19 | unix { 20 | LIBS += -L/opt/QScintilla_src-2.14.1/src -lqscintilla2_qt6 21 | } 22 | win32 { 23 | LIBS += -LC:/QScintilla_src-2.14.1/src/release -llibqscintilla2_qt6 24 | } 25 | 26 | FORMS = Resources/Forms/mainWindow.ui \ 27 | Resources/Forms/editor.ui \ 28 | Resources/Forms/projectDialog.ui \ 29 | Resources/Forms/aboutDialog.ui \ 30 | Resources/Forms/configDialog.ui \ 31 | Resources/Forms/findReplaceDialog.ui \ 32 | Resources/Forms/editorFindDialog.ui 33 | 34 | SOURCES += main.cpp \ 35 | Utils/CUtils.cpp \ 36 | Display/CMainWindow.cpp \ 37 | Display/CEditor.cpp \ 38 | Display/CEditorFindDlg.cpp \ 39 | Display/CProjectDlg.cpp \ 40 | Display/CAboutDlg.cpp \ 41 | Display/CProjectListWidget.cpp \ 42 | Display/CFileListWidget.cpp \ 43 | Display/CConfigDlg.cpp \ 44 | Display/CEventFilterObj.cpp \ 45 | Display/CSearchTextBrowser.cpp \ 46 | Display/CSearchTextEdit.cpp \ 47 | Display/CFindReplaceDlg.cpp \ 48 | Model/qTagger/CTagItem.cpp \ 49 | Model/qTagger/CTagFileRecord.cpp \ 50 | Model/qTagger/CTagResultItem.cpp \ 51 | Model/qTagger/qTagger.cpp \ 52 | Model/qTagger/CSourceFileList.cpp \ 53 | Model/qFindReplacer/qFindReplacer.cpp \ 54 | Model/CProjectListModel.cpp \ 55 | Model/CFileListModel.cpp \ 56 | Model/CProjectManager.cpp \ 57 | Model/CProjectUpdateThread.cpp \ 58 | Model/CProjectLoadThread.cpp \ 59 | Model/CConfigManager.cpp \ 60 | Model/CProjectItem.cpp \ 61 | Model/CFileItem.cpp \ 62 | Model/CRunCommand.cpp \ 63 | Model/CFindReplaceModel.cpp \ 64 | Storage/CXmlStorageHandler.cpp \ 65 | 66 | 67 | HEADERS += Utils/commonType.h \ 68 | Utils/CUtils.h \ 69 | Display/CMainWindow.h \ 70 | Display/CEditor.h \ 71 | Display/CEditorFindDlg.h \ 72 | Display/CProjectDlg.h \ 73 | Display/CAboutDlg.h \ 74 | Display/CProjectListWidget.h \ 75 | Display/CFileListWidget.h \ 76 | Display/CConfigDlg.h \ 77 | Display/CEventFilterObj.h \ 78 | Display/CSearchTextBrowser.h \ 79 | Display/CSearchTextEdit.h \ 80 | Display/CFindReplaceDlg.h \ 81 | Model/qTagger/CTagItem.h \ 82 | Model/qTagger/CTagFileRecord.h \ 83 | Model/qTagger/CTagResultItem.h \ 84 | Model/qTagger/qTagger.h \ 85 | Model/qTagger/CSourceFileList.h \ 86 | Model/qFindReplacer/qFindReplacer.h \ 87 | Model/CProjectListModel.h \ 88 | Model/CFileListModel.h \ 89 | Model/CProjectManager.h \ 90 | Model/CProjectUpdateThread.h \ 91 | Model/CProjectLoadThread.h \ 92 | Model/CConfigManager.h \ 93 | Model/CProjectItem.h \ 94 | Model/CFileItem.h \ 95 | Model/CRunCommand.h \ 96 | Model/CFindReplaceModel.h \ 97 | Storage/CXmlStorageHandler.h \ 98 | Storage/IStorageHandler.h \ 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /blinkAppImage/.DirIcon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/blinkAppImage/.DirIcon -------------------------------------------------------------------------------- /blinkAppImage/usr/share/applications/blink.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Blink 4 | Exec=/usr/bin/blink 5 | Icon=/usr/share/icons/hicolor/128x128/blink 6 | Categories=Development; 7 | -------------------------------------------------------------------------------- /blinkAppImage/usr/share/icons/hicolor/128x128/blink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ychclone/blink/958e80a15bced1d6da4b9d4d983307a0ef52dd22/blinkAppImage/usr/share/icons/hicolor/128x128/blink.png -------------------------------------------------------------------------------- /build/Html/style.css: -------------------------------------------------------------------------------- 1 | A:link {color: #0066FF; font-weight:bold; font-family: Consolas; text-decoration: none} 2 | A:visited {color: #0066FF; font-weight:bold; font-family: Consolas; text-decoration: none} 3 | A:active {color: #0066FF; font-weight:bold; font-family: Consolas; text-decoration: none} 4 | A:hover {color: #0066FF; font-weight:bold; font-family: Consolas; text-decoration: underline} 5 | 6 | functionsig {color: #33F000; font-weight:bold; font-family: Consolas;} 7 | code { background: #FAFAFA; display: table-row; font-family: Consolas; white-space: nowrap} 8 | linenum {color: #9999CC; font-family: Consolas} 9 | 10 | keyword {color: #00CCCC; font-weight:bold} 11 | body {background: #FAFAFA} 12 | 13 | .itemblock {margin: 1em 0em 1em 0.3em; padding: 0em} 14 | .header {margin: 0; padding: 0em 0em 0.3em 0em} 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /build/keyword.txt: -------------------------------------------------------------------------------- 1 | NPOS 2 | and 3 | and_eq 4 | asm 5 | auto 6 | bitand 7 | bitor 8 | bool 9 | break 10 | case 11 | char 12 | class 13 | compl 14 | const 15 | const_cast 16 | continue 17 | default 18 | defined 19 | do 20 | double 21 | dynamic_cast 22 | else 23 | enum 24 | explicit 25 | export 26 | extern 27 | false 28 | float 29 | for 30 | friend 31 | goto 32 | if 33 | include 34 | inline 35 | int 36 | long 37 | mutable 38 | namespace 39 | not 40 | not_eq 41 | operator 42 | or 43 | or_eq 44 | public 45 | protected 46 | private 47 | register 48 | reinterpret_cast 49 | return 50 | short 51 | signed 52 | sizeof 53 | static 54 | static_cast 55 | struct 56 | switch 57 | template 58 | this 59 | true 60 | try 61 | typedef 62 | typeid 63 | typename 64 | union 65 | unsigned 66 | using 67 | virtual 68 | void 69 | volatile 70 | wchar_t 71 | while 72 | xor 73 | xor_eq 74 | 75 | -------------------------------------------------------------------------------- /clean_debug.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | removeMaskList = [ 5 | "debug\*.ii", 6 | "debug\*.o", 7 | "debug\moc*.cpp", 8 | "debug\*.exe", 9 | "debug\qrc*.cpp", 10 | "ui_*.h" 11 | ] 12 | 13 | for removeMask in removeMaskList: 14 | globList = glob.glob(removeMask) 15 | for globItem in globList: 16 | os.remove(globItem) 17 | 18 | 19 | -------------------------------------------------------------------------------- /clean_makefile.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | removeMaskList = [ 5 | "*.o", 6 | "Makefile*.*", 7 | "Makefile*", 8 | "*.Debug", 9 | "*.Release", 10 | ] 11 | 12 | for removeMask in removeMaskList: 13 | globList = glob.glob(removeMask) 14 | for globItem in globList: 15 | os.remove(globItem) 16 | 17 | 18 | -------------------------------------------------------------------------------- /clean_release.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | removeMaskList = [ 5 | "release/*.ii", 6 | "release/*.o", 7 | "release/moc*.cpp", 8 | "release/*.exe", 9 | "release/qrc*.cpp", 10 | "ui_*.h" 11 | ] 12 | 13 | for removeMask in removeMaskList: 14 | globList = glob.glob(removeMask) 15 | for globItem in globList: 16 | os.remove(globItem) 17 | 18 | 19 | -------------------------------------------------------------------------------- /flatpak/io.github.ychclone.blink.yml: -------------------------------------------------------------------------------- 1 | id: io.github.ychclone.blink 2 | runtime: org.kde.Platform 3 | runtime-version: '6.7' 4 | sdk: org.kde.Sdk 5 | finish-args: 6 | - --share=ipc 7 | - --socket=fallback-x11 8 | - --socket=wayland 9 | - --device=dri 10 | command: blink 11 | modules: 12 | - name: qscintilla 13 | buildsystem: qmake 14 | subdir: src 15 | sources: 16 | - type: archive 17 | url: https://www.riverbankcomputing.com/static/Downloads/QScintilla/2.13.4/QScintilla_src-2.13.4.tar.gz 18 | sha256: 890c261f31e116f426b0ea03a136d44fc89551ebfd126d7b0bdf8a7197879986 19 | - type: patch 20 | path: qscintilla-lib-paths.patch 21 | - name: blink 22 | buildsystem: cmake-ninja 23 | builddir: true 24 | config-opts: 25 | - -DCMAKE_BUILD_TYPE=RelWithDebInfo 26 | sources: 27 | - type: archive 28 | url: https://github.com/ychclone/blink/archive/refs/tags/1.9.1.tar.gz 29 | sha256: 8e68a17582091d7d6b5199e6e0cea2c4dd6b1670144ab4ca0a3a7fec7352aa41 30 | -------------------------------------------------------------------------------- /flatpak/qscintilla-lib-paths.patch: -------------------------------------------------------------------------------- 1 | diff -ur QScintilla_src-2.13.4.orig/src/qscintilla.pro QScintilla_src-2.13.4/src/qscintilla.pro 2 | --- QScintilla_src-2.13.4.orig/src/qscintilla.pro 2023-01-15 19:13:30.751242600 +0100 3 | +++ QScintilla_src-2.13.4/src/qscintilla.pro 2023-04-18 01:42:25.794709139 +0200 4 | @@ -70,22 +70,22 @@ 5 | # Scintilla namespace rather than pollute the global namespace. 6 | #DEFINES += SCI_NAMESPACE 7 | 8 | -target.path = $$[QT_INSTALL_LIBS] 9 | +target.path = /app/lib 10 | INSTALLS += target 11 | 12 | -header.path = $$[QT_INSTALL_HEADERS] 13 | +header.path = /app/include 14 | header.files = Qsci 15 | INSTALLS += header 16 | 17 | -trans.path = $$[QT_INSTALL_TRANSLATIONS] 18 | +trans.path = /app/share/qt6/translations 19 | trans.files = qscintilla_*.qm 20 | INSTALLS += trans 21 | 22 | -qsci.path = $$[QT_INSTALL_DATA] 23 | +qsci.path = /app/share/qt6 24 | qsci.files = ../qsci 25 | INSTALLS += qsci 26 | 27 | -features.path = $$[QT_HOST_DATA]/mkspecs/features 28 | +features.path = /app/lib/qt6/mkspecs/features 29 | CONFIG(staticlib) { 30 | features.files = $$PWD/features_staticlib/qscintilla2.prf 31 | } else { 32 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "Display/CMainWindow.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "Display/CEventFilterObj.h" 7 | #include "Model/CConfigManager.h" 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | QApplication app(argc, argv); 12 | CMainWindow *window = new CMainWindow; 13 | 14 | CConfigManager* confManager; 15 | confManager = CConfigManager::getInstance(); 16 | 17 | CXmlStorageHandler xmlStorageHandler; 18 | 19 | CProjectManager::getInstance()->setProjectFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/" + "record.xml"); 20 | CProjectManager::getInstance()->setStorageHandler(xmlStorageHandler); 21 | CProjectManager::getInstance()->attachStorage(); 22 | 23 | // load profile list after storage ready 24 | window->loadProjectList(); 25 | 26 | QByteArray savedGeometry; 27 | 28 | savedGeometry = confManager->getValue("Window", "geometry").toByteArray(); 29 | window->restoreGeometry(savedGeometry); 30 | 31 | QString splitterSizeStr; 32 | QStringList splitterSizeStrList; 33 | QList splitterSizeList; 34 | 35 | QString vsplitterSizeStr; 36 | QStringList vsplitterSizeStrList; 37 | QList vsplitterSizeList; 38 | 39 | // tab widget 40 | window->restoreTabWidgetPos(); 41 | 42 | // splitter 43 | splitterSizeStr = confManager->getValue("Window", "splitter").toString(); 44 | splitterSizeStr = splitterSizeStr.trimmed(); 45 | if (splitterSizeStr != "") { 46 | splitterSizeStrList = splitterSizeStr.split(" ", Qt::SkipEmptyParts); 47 | 48 | foreach (const QString& splitterSize, splitterSizeStrList) { 49 | splitterSizeList.append(splitterSize.toInt()); 50 | } 51 | 52 | window->setSplitterSizes(splitterSizeList); 53 | } 54 | 55 | // vertical splitter 56 | vsplitterSizeStr = confManager->getValue("Window", "vsplitter").toString(); 57 | vsplitterSizeStr = vsplitterSizeStr.trimmed(); 58 | 59 | if (vsplitterSizeStr != "") { 60 | vsplitterSizeStrList = vsplitterSizeStr.split(" ", Qt::SkipEmptyParts); 61 | 62 | foreach (const QString& splitterSize, vsplitterSizeStrList) { 63 | vsplitterSizeList.append(splitterSize.toInt()); 64 | } 65 | 66 | window->setVerticalSplitterSizes(vsplitterSizeList); 67 | } 68 | 69 | qDebug() << window->geometry(); 70 | qDebug() << window->frameGeometry(); 71 | 72 | window->show(); 73 | 74 | // event filter for show/hide menuBar 75 | CEventFilterObj *keyPressObj = new CEventFilterObj(); 76 | app.installEventFilter(keyPressObj); 77 | 78 | return app.exec(); 79 | } 80 | 81 | --------------------------------------------------------------------------------