├── README.md ├── SQLiteExplorer ├── CppSQLite3.cpp ├── CppSQLite3.h ├── DataWindow.cpp ├── DataWindow.h ├── DataWindow.ui ├── DialogAbout.cpp ├── DialogAbout.h ├── DialogAbout.ui ├── GraphWindow.cpp ├── GraphWindow.h ├── GraphWindow.ui ├── HexWindow.cpp ├── HexWindow.h ├── HexWindow.ui ├── QHexEdit │ ├── QHexEdit.pri │ ├── document │ │ ├── commands │ │ │ ├── hexcommand.cpp │ │ │ ├── hexcommand.h │ │ │ ├── insertcommand.cpp │ │ │ ├── insertcommand.h │ │ │ ├── removecommand.cpp │ │ │ ├── removecommand.h │ │ │ ├── replacecommand.cpp │ │ │ └── replacecommand.h │ │ ├── gapbuffer.cpp │ │ ├── gapbuffer.h │ │ ├── metadata │ │ │ ├── qhexmetadata.cpp │ │ │ ├── qhexmetadata.h │ │ │ ├── qhexmetadataitem.cpp │ │ │ └── qhexmetadataitem.h │ │ ├── qhexcursor.cpp │ │ ├── qhexcursor.h │ │ ├── qhexdocument.cpp │ │ ├── qhexdocument.h │ │ ├── qhextheme.cpp │ │ └── qhextheme.h │ ├── paint │ │ ├── qhexmetrics.cpp │ │ ├── qhexmetrics.h │ │ ├── qhexpainter.cpp │ │ └── qhexpainter.h │ ├── qhexedit.cpp │ ├── qhexedit.h │ ├── qhexeditprivate.cpp │ └── qhexeditprivate.h ├── QSQLiteMasterTreeView │ ├── QSQLiteMasterTreeView.cpp │ ├── QSQLiteMasterTreeView.h │ ├── QSQLiteMasterTreeView.pri │ ├── QSQLiteMasterTreeViewModel.cpp │ └── QSQLiteMasterTreeViewModel.h ├── SQLWindow.cpp ├── SQLWindow.h ├── SQLWindow.ui ├── SQLite3DB.cpp ├── SQLite3DB.h ├── SQLiteExplorer.pro ├── elasticnodes │ ├── edge.cpp │ ├── edge.h │ ├── elasticnodes.pri │ ├── graphwidget.cpp │ ├── graphwidget.h │ ├── main.cpp │ ├── node.cpp │ └── node.h ├── graphviz-2.38.zip ├── highlighter.cpp ├── highlighter.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── pixitem.cpp ├── pixitem.h ├── qsqlitetableview.cpp ├── qsqlitetableview.h ├── ui │ ├── 0.png │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 17.png │ ├── 18.png │ ├── 19.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.png │ ├── app.ico │ ├── app.png │ ├── db.png │ ├── find.png │ ├── freelist.png │ ├── index.jpg │ ├── info.png │ ├── new.png │ ├── question.png │ ├── setting.png │ ├── table.png │ ├── trigger.png │ └── view.png ├── ui_icon.qrc ├── utils.cpp └── utils.h ├── SQLiteSolution.pro ├── art ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── FreeListTrunk.jpg ├── FreelistGraph.jpg ├── FreelistLeaf.jpg ├── GraphViz.jpg ├── GraphWidget.jpg ├── HexWindow.jpg ├── IndexGraph.jpg ├── IndexInterior.jpg ├── IndexLeaf.jpg ├── TableGraph.jpg ├── TableInterior.jpg └── TableLeaf.jpg ├── sqlite3 ├── shell.c ├── sqlite3.c ├── sqlite3.def ├── sqlite3.h ├── sqlite3.pro └── sqlite3ext.h └── test └── test.db /README.md: -------------------------------------------------------------------------------- 1 | # SQLiteExplorer 2 | 该项目旨在创建一个查看SQLite文件结构的工具软件(SQLite3 File Format Tools),用以方便对SQLite文件格式的学习。 3 | 这里有需要的链接: 4 | 5 | 该工程使用Qt5 MingW版编译的。 6 | 7 | SQLite3 File Format: 8 | https://sqlite.org/fileformat.html 9 | 10 | GraphViz: 11 | http://www.graphviz.org/ 12 | 13 | 14 | 目前实现效果图如下: 15 | 16 | ## 1. Database界面 17 | 该界面主要显示数据库属性 18 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/1.png) 19 | 20 | ## 2. Data界面 21 | 该界面主要展示表数据。目前采用滚动加载方式,防止一次加载数据过多导致卡死。 22 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/2.png) 23 | 24 | ## 3. SQL界面 25 | sql语句查询界面,查询结果也是采用Data界面方式滚动加载。 26 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/3.png) 27 | 28 | ## 4. Design界面 29 | 表设计界面,展示表含有的列编号,列名称,类型,非空,默认值以及主键情况。 30 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/4.png) 31 | 32 | ## 5. HexWindow界面 33 | HexWindow界面目前支持IndexInterior,IndexLeaf,TableInterior,TableLeaf,FreelistTrunkPage,FreelistLeafPage,Overflow页面的解析: 34 | 35 | ### 5.1 索引内部页 IndexInterior 36 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/IndexInterior.jpg) 37 | 38 | ### 5.2 索引叶子页 IndexLeaf 39 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/IndexLeaf.jpg) 40 | 41 | ### 5.3 表内部页 TableInterior 42 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/TableInterior.jpg) 43 | 44 | ### 5.4 表叶子页 TableLeaf 45 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/TableLeaf.jpg) 46 | 47 | ### 5.5 自由页主干页 FreelistTrunkPage 48 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/FreeListTrunk.jpg) 49 | 50 | ### 5.6 自由页叶子页 FreelistLeafPage 51 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/FreelistLeaf.jpg) 52 | 53 | ## 6. DDL界面 54 | 展示建表语句。 55 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/6.png) 56 | 57 | ## 7. Graph界面 58 | 目前支持Index,Table,Freelist的页组织形式的显示。 59 | 60 | ### 7.1 索引图 61 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/IndexGraph.jpg) 62 | 63 | ### 7.2 表图 64 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/TableGraph.jpg) 65 | 66 | ### 7.3 自由页图 67 | ![image](https://gitee.com/chuck_wilson/SQLiteExplorer/raw/master/art/FreelistGraph.jpg) 68 | -------------------------------------------------------------------------------- /SQLiteExplorer/CppSQLite3.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // CppSQLite3 - A C++ wrapper around the SQLite3 embedded database library. 3 | // 4 | // Copyright (c) 2004..2007 Rob Groves. All Rights Reserved. rob.groves@btinternet.com 5 | // 6 | // Permission to use, copy, modify, and distribute this software and its 7 | // documentation for any purpose, without fee, and without a written 8 | // agreement, is hereby granted, provided that the above copyright notice, 9 | // this paragraph and the following two paragraphs appear in all copies, 10 | // modifications, and distributions. 11 | // 12 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, 13 | // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 14 | // PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 15 | // EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | // 17 | // THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | // PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF 20 | // ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION 21 | // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22 | // 23 | // V3.0 03/08/2004 -Initial Version for sqlite3 24 | // 25 | // V3.1 16/09/2004 -Implemented getXXXXField using sqlite3 functions 26 | // -Added CppSQLiteDB3::tableExists() 27 | // 28 | // V3.2 01/07/2005 -Fixed execScalar to handle a NULL result 29 | // 12/07/2007 -Added CppSQLiteDB::IsAutoCommitOn() 30 | // -Added int64 functions to CppSQLite3Query 31 | // -Added Name based parameter binding to CppSQLite3Statement. 32 | //////////////////////////////////////////////////////////////////////////////// 33 | #ifndef _CppSQLite3_H_ 34 | #define _CppSQLite3_H_ 35 | #define _CRT_SECURE_NO_WARNINGS 36 | 37 | #include "sqlite3.h" 38 | #include 39 | #include 40 | 41 | 42 | #define CPPSQLITE_ERROR 1000 43 | 44 | class CppSQLite3Exception 45 | { 46 | public: 47 | 48 | CppSQLite3Exception(const int nErrCode, 49 | char* szErrMess, 50 | bool bDeleteMsg=true); 51 | 52 | CppSQLite3Exception(const CppSQLite3Exception& e); 53 | 54 | virtual ~CppSQLite3Exception(); 55 | 56 | const int errorCode() { return mnErrCode; } 57 | 58 | const char* errorMessage() { return mpszErrMess; } 59 | 60 | static const char* errorCodeAsString(int nErrCode); 61 | 62 | private: 63 | 64 | int mnErrCode; 65 | char* mpszErrMess; 66 | }; 67 | 68 | 69 | class CppSQLite3Buffer 70 | { 71 | public: 72 | 73 | CppSQLite3Buffer(); 74 | 75 | ~CppSQLite3Buffer(); 76 | 77 | const char* format(const char* szFormat, ...); 78 | 79 | operator const char*() { return mpBuf; } 80 | 81 | void clear(); 82 | 83 | const char* c_str() { return mpBuf; } 84 | 85 | private: 86 | 87 | char* mpBuf; 88 | }; 89 | 90 | 91 | class CppSQLite3Binary 92 | { 93 | public: 94 | 95 | CppSQLite3Binary(); 96 | 97 | ~CppSQLite3Binary(); 98 | 99 | void setBinary(const unsigned char* pBuf, int nLen); 100 | void setEncoded(const unsigned char* pBuf); 101 | 102 | const unsigned char* getEncoded(); 103 | const unsigned char* getBinary(); 104 | 105 | int getBinaryLength(); 106 | 107 | unsigned char* allocBuffer(int nLen); 108 | 109 | void clear(); 110 | 111 | private: 112 | 113 | unsigned char* mpBuf; 114 | int mnBinaryLen; 115 | int mnBufferLen; 116 | int mnEncodedLen; 117 | bool mbEncoded; 118 | }; 119 | 120 | 121 | class CppSQLite3Query 122 | { 123 | public: 124 | 125 | CppSQLite3Query(); 126 | 127 | CppSQLite3Query(const CppSQLite3Query& rQuery); 128 | 129 | CppSQLite3Query(sqlite3* pDB, 130 | sqlite3_stmt* pVM, 131 | bool bEof, 132 | bool bOwnVM=true); 133 | 134 | CppSQLite3Query& operator=(const CppSQLite3Query& rQuery); 135 | 136 | virtual ~CppSQLite3Query(); 137 | 138 | int numFields(); 139 | 140 | int fieldIndex(const char* szField); 141 | const char* fieldName(int nCol); 142 | 143 | const char* fieldDeclType(int nCol); 144 | int fieldDataType(int nCol); 145 | 146 | const char* fieldValue(int nField); 147 | const char* fieldValue(const char* szField); 148 | 149 | int getIntField(int nField, int nNullValue=0); 150 | int getIntField(const char* szField, int nNullValue=0); 151 | 152 | sqlite_int64 getInt64Field(int nField, sqlite_int64 nNullValue=0); 153 | sqlite_int64 getInt64Field(const char* szField, sqlite_int64 nNullValue=0); 154 | 155 | double getFloatField(int nField, double fNullValue=0.0); 156 | double getFloatField(const char* szField, double fNullValue=0.0); 157 | 158 | const char* getStringField(int nField, const char* szNullValue=""); 159 | const char* getStringField(const char* szField, const char* szNullValue=""); 160 | 161 | const unsigned char* getBlobField(int nField, int& nLen); 162 | const unsigned char* getBlobField(const char* szField, int& nLen); 163 | 164 | bool fieldIsNull(int nField); 165 | bool fieldIsNull(const char* szField); 166 | 167 | bool eof(); 168 | 169 | void nextRow(); 170 | 171 | void finalize(); 172 | 173 | private: 174 | 175 | void checkVM(); 176 | 177 | sqlite3* mpDB; 178 | sqlite3_stmt* mpVM; 179 | bool mbEof; 180 | int mnCols; 181 | bool mbOwnVM; 182 | }; 183 | 184 | 185 | class CppSQLite3Table 186 | { 187 | public: 188 | 189 | CppSQLite3Table(); 190 | 191 | CppSQLite3Table(const CppSQLite3Table& rTable); 192 | 193 | CppSQLite3Table(char** paszResults, int nRows, int nCols); 194 | 195 | virtual ~CppSQLite3Table(); 196 | 197 | CppSQLite3Table& operator=(const CppSQLite3Table& rTable); 198 | 199 | int numFields(); 200 | 201 | int numRows(); 202 | 203 | const char* fieldName(int nCol); 204 | 205 | const char* fieldValue(int nField); 206 | const char* fieldValue(const char* szField); 207 | 208 | int getIntField(int nField, int nNullValue=0); 209 | int getIntField(const char* szField, int nNullValue=0); 210 | 211 | double getFloatField(int nField, double fNullValue=0.0); 212 | double getFloatField(const char* szField, double fNullValue=0.0); 213 | 214 | const char* getStringField(int nField, const char* szNullValue=""); 215 | const char* getStringField(const char* szField, const char* szNullValue=""); 216 | 217 | bool fieldIsNull(int nField); 218 | bool fieldIsNull(const char* szField); 219 | 220 | void setRow(int nRow); 221 | 222 | void finalize(); 223 | 224 | private: 225 | 226 | void checkResults(); 227 | 228 | int mnCols; 229 | int mnRows; 230 | int mnCurrentRow; 231 | char** mpaszResults; 232 | }; 233 | 234 | 235 | class CppSQLite3Statement 236 | { 237 | public: 238 | 239 | CppSQLite3Statement(); 240 | 241 | CppSQLite3Statement(const CppSQLite3Statement& rStatement); 242 | 243 | CppSQLite3Statement(sqlite3* pDB, sqlite3_stmt* pVM); 244 | 245 | virtual ~CppSQLite3Statement(); 246 | 247 | CppSQLite3Statement& operator=(const CppSQLite3Statement& rStatement); 248 | 249 | int execDML(); 250 | 251 | CppSQLite3Query execQuery(); 252 | void bind(int nParam, const sqlite_int64 int64value); 253 | void bind(int nParam, const sqlite_uint64 uint64value); 254 | void bind(int nParam, const char* szValue); 255 | void bind(int nParam, const int nValue); 256 | void bind(int nParam, const double dwValue); 257 | void bind(int nParam, const unsigned char* blobValue, int nLen); 258 | void bindNull(int nParam); 259 | 260 | int bindParameterIndex(const char* szParam); 261 | void bind(const char* szParam, const sqlite_int64 int64value); 262 | void bind(const char* szParam, const sqlite_uint64 uint64value); 263 | void bind(const char* szParam, const char* szValue); 264 | void bind(const char* szParam, const int nValue); 265 | void bind(const char* szParam, const double dwValue); 266 | void bind(const char* szParam, const unsigned char* blobValue, int nLen); 267 | void bindNull(const char* szParam); 268 | 269 | void reset(); 270 | 271 | void finalize(); 272 | 273 | private: 274 | 275 | void checkDB(); 276 | void checkVM(); 277 | 278 | sqlite3* mpDB; 279 | sqlite3_stmt* mpVM; 280 | }; 281 | 282 | 283 | class CppSQLite3DB 284 | { 285 | public: 286 | 287 | CppSQLite3DB(); 288 | 289 | virtual ~CppSQLite3DB(); 290 | 291 | void open(const char* szFile); 292 | 293 | void close(); 294 | 295 | bool tableExists(const char* szTable); 296 | 297 | int execDML(const char* szSQL); 298 | 299 | CppSQLite3Query execQuery(const char* szSQL); 300 | 301 | int execScalar(const char* szSQL, int nNullValue=0); 302 | 303 | CppSQLite3Table getTable(const char* szSQL); 304 | 305 | CppSQLite3Statement compileStatement(const char* szSQL); 306 | 307 | sqlite_int64 lastRowId(); 308 | 309 | void interrupt() { sqlite3_interrupt(mpDB); } 310 | 311 | void setBusyTimeout(int nMillisecs); 312 | 313 | static const char* SQLiteVersion() { return SQLITE_VERSION; } 314 | static const char* SQLiteHeaderVersion() { return SQLITE_VERSION; } 315 | static const char* SQLiteLibraryVersion() { return sqlite3_libversion(); } 316 | static int SQLiteLibraryVersionNumber() { return sqlite3_libversion_number(); } 317 | 318 | bool IsAutoCommitOn(); 319 | 320 | protected: 321 | 322 | CppSQLite3DB(const CppSQLite3DB& db); 323 | CppSQLite3DB& operator=(const CppSQLite3DB& db); 324 | 325 | sqlite3_stmt* compile(const char* szSQL); 326 | 327 | void checkDB(); 328 | 329 | sqlite3* mpDB; 330 | int mnBusyTimeoutMs; 331 | }; 332 | 333 | #endif 334 | -------------------------------------------------------------------------------- /SQLiteExplorer/DataWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "DataWindow.h" 2 | #include "ui_DataWindow.h" 3 | #include 4 | DataWindow::DataWindow(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::DataWindow) 7 | { 8 | ui->setupUi(this); 9 | 10 | m_pParent = qobject_cast(parent); 11 | 12 | connect(ui->tableWidget, SIGNAL(dataLoaded(QString)), this, SLOT(onDataLoaded(QString))); 13 | } 14 | 15 | DataWindow::~DataWindow() 16 | { 17 | delete ui; 18 | } 19 | 20 | void DataWindow::clear() 21 | { 22 | ui->tableWidget->clear(); 23 | ui->tableWidget->setRowCount(0); 24 | ui->tableWidget->setColumnCount(0); 25 | ui->label->clear(); 26 | } 27 | 28 | void DataWindow::onSQLiteQueryReceived(const QString &sql) 29 | { 30 | if(m_pParent) 31 | { 32 | ui->tableWidget->SetDb(m_pParent->GetCurSQLite3DB()); 33 | } 34 | ui->tableWidget->onSQLiteQueryReceived(sql); 35 | } 36 | 37 | void DataWindow::onDataLoaded(const QString &msg) 38 | { 39 | ui->label->setText(msg); 40 | } 41 | -------------------------------------------------------------------------------- /SQLiteExplorer/DataWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef DATAWINDOW_H 2 | #define DATAWINDOW_H 3 | 4 | #include 5 | 6 | 7 | namespace Ui { 8 | class DataWindow; 9 | } 10 | class MainWindow; 11 | class DataWindow : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit DataWindow(QWidget *parent = 0); 17 | ~DataWindow(); 18 | 19 | void clear(); 20 | 21 | public slots: 22 | void onSQLiteQueryReceived(const QString& sql); 23 | void onDataLoaded(const QString& msg); 24 | private: 25 | MainWindow* m_pParent; 26 | Ui::DataWindow *ui; 27 | }; 28 | 29 | #endif // DATAWINDOW_H 30 | -------------------------------------------------------------------------------- /SQLiteExplorer/DataWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DataWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 629 10 | 337 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 16777215 25 | 50 26 | 27 | 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 0 37 | 38 | 39 | 0 40 | 41 | 42 | 0 43 | 44 | 45 | 46 | 47 | Status 48 | 49 | 50 | 51 | 52 | 53 | 54 | Qt::Horizontal 55 | 56 | 57 | 58 | 572 59 | 20 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | QSQLiteTableView 72 | QTableWidget 73 |
qsqlitetableview.h
74 |
75 |
76 | 77 | 78 |
79 | -------------------------------------------------------------------------------- /SQLiteExplorer/DialogAbout.cpp: -------------------------------------------------------------------------------- 1 | #include "DialogAbout.h" 2 | #include "ui_DialogAbout.h" 3 | 4 | DialogAbout::DialogAbout(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::DialogAbout) 7 | { 8 | ui->setupUi(this); 9 | 10 | setWindowTitle("SQLiteExplorer"); 11 | } 12 | 13 | DialogAbout::~DialogAbout() 14 | { 15 | delete ui; 16 | } 17 | -------------------------------------------------------------------------------- /SQLiteExplorer/DialogAbout.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGABOUT_H 2 | #define DIALOGABOUT_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class DialogAbout; 8 | } 9 | 10 | class DialogAbout : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit DialogAbout(QWidget *parent = 0); 16 | ~DialogAbout(); 17 | 18 | private: 19 | Ui::DialogAbout *ui; 20 | }; 21 | 22 | #endif // DIALOGABOUT_H 23 | -------------------------------------------------------------------------------- /SQLiteExplorer/DialogAbout.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogAbout 4 | 5 | 6 | 7 | 0 8 | 0 9 | 357 10 | 126 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | Qt::Vertical 21 | 22 | 23 | 24 | 20 25 | 40 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 这是一个用来查看SQLite3文件的工具软件,欢迎大家使用。 34 | 35 | 36 | 37 | 38 | 39 | 40 | Qt::Vertical 41 | 42 | 43 | 44 | 20 45 | 40 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Qt::Horizontal 57 | 58 | 59 | 60 | 201 61 | 20 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | By Chuck Wilson 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Qt::Horizontal 80 | 81 | 82 | QDialogButtonBox::Ok 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | buttonBox 92 | accepted() 93 | DialogAbout 94 | accept() 95 | 96 | 97 | 248 98 | 254 99 | 100 | 101 | 157 102 | 274 103 | 104 | 105 | 106 | 107 | buttonBox 108 | rejected() 109 | DialogAbout 110 | reject() 111 | 112 | 113 | 316 114 | 260 115 | 116 | 117 | 286 118 | 274 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /SQLiteExplorer/GraphWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphWindow.h" 2 | #include "ui_graphwindow.h" 3 | 4 | GraphWindow::GraphWindow(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::GraphWindow) 7 | { 8 | ui->setupUi(this); 9 | 10 | connect(ui->pushButton, SIGNAL(clicked(bool)), ui->graphWidget, SLOT(StartAnimate(bool))); 11 | 12 | m_graphicsScene = new QGraphicsScene; 13 | m_graphicsItem = new PixItem; 14 | m_graphicsView = new MyGraphicsView(this); 15 | m_graphicsScene->addItem(m_graphicsItem); 16 | m_graphicsView->setScene(m_graphicsScene); 17 | 18 | QVBoxLayout* layout = new QVBoxLayout; 19 | layout->setSpacing(0); 20 | layout->setMargin(0); 21 | layout->addWidget(m_graphicsView); 22 | ui->tab_2->setLayout(layout); 23 | } 24 | 25 | GraphWindow::~GraphWindow() 26 | { 27 | delete ui; 28 | } 29 | 30 | void GraphWindow::clear() 31 | { 32 | m_graphicsScene->clear(); 33 | ui->graphWidget; 34 | } 35 | 36 | void GraphWindow::SetPath(QString path) 37 | { 38 | if(path == "tmp.plain") 39 | { 40 | ui->graphWidget->SetPath(path); 41 | } 42 | else 43 | { 44 | QPixmap px; 45 | px.load(path); 46 | 47 | m_graphicsItem->setPixmap(px); 48 | m_graphicsItem->setPos(0,0); 49 | m_graphicsItem->setZoomState(1); 50 | qreal w = px.width(); 51 | qreal h = px.height(); 52 | m_graphicsScene->setSceneRect(-1*(w/2), -1*(h/2), w, h); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SQLiteExplorer/GraphWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHWINDOW_H 2 | #define GRAPHWINDOW_H 3 | 4 | #include 5 | #include "pixitem.h" 6 | 7 | namespace Ui { 8 | class GraphWindow; 9 | } 10 | 11 | class GraphWindow : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit GraphWindow(QWidget *parent = 0); 17 | ~GraphWindow(); 18 | 19 | void clear(); 20 | 21 | void SetPath(QString path); 22 | private: 23 | Ui::GraphWindow *ui; 24 | 25 | QGraphicsScene* m_graphicsScene; 26 | PixItem* m_graphicsItem; 27 | QGraphicsView* m_graphicsView; 28 | }; 29 | 30 | #endif // GRAPHWINDOW_H 31 | -------------------------------------------------------------------------------- /SQLiteExplorer/GraphWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | GraphWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 372 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | 0 36 | 37 | 38 | 39 | GraphWidget 40 | 41 | 42 | 43 | 0 44 | 45 | 46 | 0 47 | 48 | 49 | 0 50 | 51 | 52 | 0 53 | 54 | 55 | 0 56 | 57 | 58 | 59 | 60 | 61 | 16777215 62 | 40 63 | 64 | 65 | 66 | 67 | 6 68 | 69 | 70 | 9 71 | 72 | 73 | 9 74 | 75 | 76 | 9 77 | 78 | 79 | 9 80 | 81 | 82 | 83 | 84 | StartAnimate 85 | 86 | 87 | 88 | 89 | 90 | 91 | Qt::Horizontal 92 | 93 | 94 | 95 | 40 96 | 20 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | GraphViz 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | GraphWidget 121 | QWidget 122 |
graphwidget.h
123 | 1 124 |
125 |
126 | 127 | 128 |
129 | -------------------------------------------------------------------------------- /SQLiteExplorer/HexWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXWINDOW_H 2 | #define QHEXWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "SQLite3DB.h" 13 | 14 | #include 15 | using namespace std; 16 | 17 | namespace Ui { 18 | class HexWindow; 19 | } 20 | 21 | class MainWindow; 22 | class HexWindow : public QWidget 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | explicit HexWindow(QWidget *parent = 0); 28 | ~HexWindow(); 29 | 30 | void clear(); 31 | 32 | void SetPageNosAndType(const vector>& pgs); 33 | void SetTableName(const QString& name, const QString& tableName, const QString& type); 34 | 35 | void setPageHdrData(PageType type, ContentArea& pageHeaderArea, ContentArea& cellidxArea, ContentArea& unusedArea, int pgno, string raw); 36 | void setFreeListPageHdrData(ContentArea &sNextTrunkPageNo, int &nNextTrunkPageNo, 37 | ContentArea &sLeafPageCounts, int &nLeafPageCounts, 38 | vector &sLeafPageNos, vector &nLeafPageNos, 39 | ContentArea &sUnused, string raw); 40 | 41 | QStandardItem *setCellData(QStandardItem *parentItem, CSQLite3Payload& payload, ContentArea area, string raw); 42 | 43 | QStandardItem* GetItem(int start, i64 len, QString txt); 44 | public slots: 45 | void onPageIdSelect(int pgno, PageType type); 46 | void onPageTypeChanged(const QString& item); 47 | void onComboxChanged(const QString& item); 48 | void onPrevBtnClicked(); 49 | void onNextBtnClicked(); 50 | void onFirstBtnClicked(); 51 | void onLastBtnClicked(); 52 | 53 | void onCurrentAddressChanged(qint64 address); 54 | void onCheckBoxStatChanged(bool stat); 55 | 56 | private: 57 | void setPushBtnStats(); 58 | 59 | 60 | private: 61 | Ui::HexWindow *ui; 62 | 63 | QTreeView* m_pPageView; 64 | QStandardItemModel* m_pPageViewModel; 65 | 66 | QSplitter* m_pHSplitter; 67 | QSplitter* m_pSplitter; 68 | QHexEdit* m_pHexEdit; 69 | QTableWidget* m_pTableWdiget; 70 | 71 | MainWindow* m_pParent; 72 | CSQLite3DB* m_pCurSQLite3DB; 73 | 74 | QString m_curTableName; 75 | QString m_curName; 76 | 77 | QStringList m_tableHeaders; 78 | vector m_payloadArea; 79 | 80 | QMap m_pageTypeName; 81 | QStringList m_pageNoAndTypes; 82 | 83 | QMap m_mapItems; 84 | uint m_curPageNo; 85 | }; 86 | 87 | #endif // QHEXWINDOW_H 88 | -------------------------------------------------------------------------------- /SQLiteExplorer/HexWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | HexWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 941 10 | 432 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 22 | 23 | 24 | 0 25 | 40 26 | 27 | 28 | 29 | 30 | 16777215 31 | 40 32 | 33 | 34 | 35 | 36 | 0 37 | 38 | 39 | 0 40 | 41 | 42 | 0 43 | 44 | 45 | 0 46 | 47 | 48 | 49 | 50 | 51 | 150 52 | 0 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 40 62 | 16777215 63 | 64 | 65 | 66 | |< 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 40 75 | 16777215 76 | 77 | 78 | 79 | < 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 150 88 | 0 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 40 98 | 16777215 99 | 100 | 101 | 102 | > 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 40 111 | 16777215 112 | 113 | 114 | 115 | >| 116 | 117 | 118 | 119 | 120 | 121 | 122 | SetBaseAddress 123 | 124 | 125 | 126 | 127 | 128 | 129 | Qt::Horizontal 130 | 131 | 132 | 133 | 40 134 | 20 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 16777215 147 | 40 148 | 149 | 150 | 151 | 152 | 6 153 | 154 | 155 | 0 156 | 157 | 158 | 0 159 | 160 | 161 | 0 162 | 163 | 164 | 9 165 | 166 | 167 | 168 | 169 | 170 | 40 171 | 0 172 | 173 | 174 | 175 | 176 | 40 177 | 16777215 178 | 179 | 180 | 181 | background-color: rgb(106, 136, 130); 182 | 183 | 184 | 185 | 186 | 187 | 188 | PgHdr 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 40 197 | 0 198 | 199 | 200 | 201 | 202 | 40 203 | 16777215 204 | 205 | 206 | 207 | background-color: rgb(233, 253, 242); 208 | 209 | 210 | 211 | 212 | 213 | 214 | CellPtr 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 40 223 | 0 224 | 225 | 226 | 227 | 228 | 40 229 | 16777215 230 | 231 | 232 | 233 | background-color: rgb(254, 227, 186); 234 | 235 | 236 | 237 | 238 | 239 | 240 | Unallocated 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 40 249 | 0 250 | 251 | 252 | 253 | 254 | 40 255 | 16777215 256 | 257 | 258 | 259 | background-color: rgb(98, 197, 68); 260 | 261 | 262 | 263 | 264 | 265 | 266 | Active 267 | 268 | 269 | 270 | 271 | 272 | 273 | Qt::Horizontal 274 | 275 | 276 | 277 | 40 278 | 20 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/QHexEdit.pri: -------------------------------------------------------------------------------- 1 | HEADERS += $$PWD/document/commands/hexcommand.h \ 2 | $$PWD/document/commands/insertcommand.h \ 3 | $$PWD/document/commands/removecommand.h \ 4 | $$PWD/document/commands/replacecommand.h \ 5 | $$PWD/document/gapbuffer.h \ 6 | $$PWD/document/qhexcursor.h \ 7 | $$PWD/document/qhexdocument.h \ 8 | $$PWD/document/qhextheme.h \ 9 | $$PWD/paint/qhexmetrics.h \ 10 | $$PWD/paint/qhexpainter.h \ 11 | $$PWD/qhexedit.h \ 12 | $$PWD/qhexeditprivate.h \ 13 | $$PWD/document/metadata/qhexmetadataitem.h \ 14 | $$PWD/document/metadata/qhexmetadata.h 15 | 16 | SOURCES += $$PWD/document/commands/hexcommand.cpp \ 17 | $$PWD/document/commands/insertcommand.cpp \ 18 | $$PWD/document/commands/removecommand.cpp \ 19 | $$PWD/document/commands/replacecommand.cpp \ 20 | $$PWD/document/gapbuffer.cpp \ 21 | $$PWD/document/qhexcursor.cpp \ 22 | $$PWD/document/qhexdocument.cpp \ 23 | $$PWD/document/qhextheme.cpp \ 24 | $$PWD/paint/qhexmetrics.cpp \ 25 | $$PWD/paint/qhexpainter.cpp \ 26 | $$PWD/qhexedit.cpp \ 27 | $$PWD/qhexeditprivate.cpp \ 28 | $$PWD/document/metadata/qhexmetadataitem.cpp \ 29 | $$PWD/document/metadata/qhexmetadata.cpp 30 | 31 | INCLUDEPATH += $$PWD 32 | 33 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/hexcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "hexcommand.h" 2 | 3 | HexCommand::HexCommand(GapBuffer *gapbuffer, QUndoCommand *parent): QUndoCommand(parent), _gapbuffer(gapbuffer), _offset(0), _length(0) 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/hexcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef HEXCOMMAND_H 2 | #define HEXCOMMAND_H 3 | 4 | #include 5 | #include "../gapbuffer.h" 6 | 7 | class HexCommand: public QUndoCommand 8 | { 9 | public: 10 | HexCommand(GapBuffer* gapbuffer, QUndoCommand* parent = 0); 11 | 12 | protected: 13 | GapBuffer* _gapbuffer; 14 | integer_t _offset, _length; 15 | QByteArray _data; 16 | }; 17 | 18 | #endif // HEXCOMMAND_H 19 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/insertcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "insertcommand.h" 2 | 3 | InsertCommand::InsertCommand(GapBuffer *gapbuffer, integer_t offset, const QByteArray &data, QUndoCommand *parent): HexCommand(gapbuffer, parent) 4 | { 5 | this->_offset = offset; 6 | this->_data = data; 7 | } 8 | 9 | void InsertCommand::undo() 10 | { 11 | this->_gapbuffer->remove(this->_offset, this->_data.length()); 12 | } 13 | 14 | void InsertCommand::redo() 15 | { 16 | this->_gapbuffer->insert(this->_offset, this->_data); 17 | } 18 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/insertcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef INSERTCOMMAND_H 2 | #define INSERTCOMMAND_H 3 | 4 | #include "hexcommand.h" 5 | 6 | class InsertCommand: public HexCommand 7 | { 8 | public: 9 | InsertCommand(GapBuffer* gapbuffer, integer_t offset, const QByteArray& data, QUndoCommand* parent = 0); 10 | virtual void undo(); 11 | virtual void redo(); 12 | }; 13 | 14 | #endif // INSERTCOMMAND_H 15 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/removecommand.cpp: -------------------------------------------------------------------------------- 1 | #include "removecommand.h" 2 | 3 | RemoveCommand::RemoveCommand(GapBuffer *gapbuffer, integer_t offset, integer_t length, QUndoCommand *parent): HexCommand(gapbuffer, parent) 4 | { 5 | this->_offset = offset; 6 | this->_length = length; 7 | } 8 | 9 | void RemoveCommand::undo() 10 | { 11 | this->_gapbuffer->insert(this->_offset, this->_data); 12 | } 13 | 14 | void RemoveCommand::redo() 15 | { 16 | this->_data = this->_gapbuffer->read(this->_offset, this->_length); // Backup data 17 | this->_gapbuffer->remove(this->_offset, this->_length); 18 | } 19 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/removecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef REMOVECOMMAND_H 2 | #define REMOVECOMMAND_H 3 | 4 | #include "hexcommand.h" 5 | 6 | class RemoveCommand: public HexCommand 7 | { 8 | public: 9 | RemoveCommand(GapBuffer* gapbuffer, integer_t offset, integer_t length, QUndoCommand* parent = 0); 10 | virtual void undo(); 11 | virtual void redo(); 12 | }; 13 | 14 | #endif // REMOVECOMMAND_H 15 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/replacecommand.cpp: -------------------------------------------------------------------------------- 1 | #include "replacecommand.h" 2 | 3 | ReplaceCommand::ReplaceCommand(GapBuffer *gapbuffer, integer_t offset, const QByteArray &data, QUndoCommand *parent): HexCommand(gapbuffer, parent) 4 | { 5 | this->_offset = offset; 6 | this->_data = data; 7 | } 8 | 9 | void ReplaceCommand::undo() 10 | { 11 | this->_gapbuffer->replace(this->_offset, this->_olddata); 12 | } 13 | 14 | void ReplaceCommand::redo() 15 | { 16 | this->_olddata = this->_gapbuffer->read(this->_offset, this->_data.length()); 17 | this->_gapbuffer->replace(this->_offset, this->_data); 18 | } 19 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/commands/replacecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef REPLACECOMMAND_H 2 | #define REPLACECOMMAND_H 3 | 4 | #include "hexcommand.h" 5 | 6 | class ReplaceCommand: public HexCommand 7 | { 8 | public: 9 | ReplaceCommand(GapBuffer* gapbuffer, integer_t offset, const QByteArray& data, QUndoCommand* parent = 0); 10 | virtual void undo(); 11 | virtual void redo(); 12 | 13 | private: 14 | QByteArray _olddata; 15 | }; 16 | 17 | #endif // REPLACECOMMAND_H 18 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/gapbuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "gapbuffer.h" 2 | #include 3 | 4 | #define BASE_GAP_SIZE 65536 // 64k buffer 5 | //#define BASE_GAP_SIZE 4 6 | 7 | GapBuffer::GapBuffer(): _gapstart(0), _gapend(BASE_GAP_SIZE), _gapminlength(BASE_GAP_SIZE) 8 | { 9 | } 10 | 11 | GapBuffer::GapBuffer(QIODevice *device): GapBuffer() 12 | { 13 | this->init(device); 14 | } 15 | 16 | GapBuffer::~GapBuffer() 17 | { 18 | } 19 | 20 | void GapBuffer::insert(integer_t index, const QByteArray &data) 21 | { 22 | this->moveGap(index, data.length()); 23 | 24 | this->_buffer.replace(this->_gapstart, data.length(), data); 25 | this->_gapstart += data.length(); 26 | } 27 | 28 | void GapBuffer::replace(integer_t index, const QByteArray &data) 29 | { 30 | if(index < this->_gapstart) 31 | { 32 | sinteger_t len = this->_gapstart - index; 33 | this->_buffer.replace(index, len, data.left(len)); 34 | 35 | if(len < data.length()) // More data to be copied to the other side of the gap 36 | { 37 | index = this->_gapend; 38 | this->_buffer.replace(index, data.length() - len, data.mid(len)); 39 | } 40 | 41 | return; 42 | } 43 | 44 | index += this->gapLength(); 45 | this->_buffer.replace(index, data.length(), data); 46 | } 47 | 48 | void GapBuffer::remove(integer_t index, integer_t len) 49 | { 50 | this->moveGap(index, 0); 51 | 52 | #ifdef GAP_BUFFER_TIDY 53 | this->_buffer.replace(index, len, QByteArray(len, 0x00)); 54 | #endif 55 | 56 | this->_gapend += len; 57 | } 58 | 59 | char GapBuffer::at(integer_t index) const 60 | { 61 | if(index >= this->length()) 62 | throw std::runtime_error("Index out of range"); 63 | 64 | if(index >= this->_gapstart) 65 | index += this->gapLength(); 66 | 67 | return this->_buffer.at(index); 68 | } 69 | 70 | QByteArray GapBuffer::read(integer_t index, integer_t len) const 71 | { 72 | if(len == 0) 73 | len = this->length(); 74 | 75 | QByteArray ba; 76 | ba.reserve(len); 77 | 78 | if(index < this->_gapstart) 79 | { 80 | ba.append(this->_buffer.mid(index, std::min(len, this->_gapstart - index))); 81 | index += ba.length(); 82 | len -= ba.length(); 83 | } 84 | 85 | if(index >= this->_gapstart) 86 | index += this->_gapend; 87 | 88 | ba.append(this->_buffer.mid(index, len)); 89 | return ba; 90 | } 91 | 92 | QByteArray GapBuffer::toByteArray() const 93 | { 94 | return this->_buffer.mid(0, this->_gapstart) + this->_buffer.mid(this->_gapend); 95 | } 96 | 97 | integer_t GapBuffer::length() const 98 | { 99 | return this->_buffer.length() - this->gapLength(); 100 | } 101 | 102 | integer_t GapBuffer::gapLength() const 103 | { 104 | return this->_gapend - this->_gapstart; 105 | } 106 | 107 | void GapBuffer::moveGap(integer_t index, integer_t len) 108 | { 109 | this->expandGap(len); 110 | 111 | if(index == this->_gapstart) 112 | return; 113 | 114 | sinteger_t delta = index - this->_gapstart; 115 | char* pdata = this->_buffer.data(); 116 | 117 | if(delta < 0) // Move gap left 118 | std::memcpy(pdata + (this->_gapend + delta), pdata + index, -delta); 119 | else // Move gap right 120 | std::memcpy(pdata + this->_gapstart, pdata + this->_gapend, delta); 121 | 122 | this->_gapstart += delta; 123 | this->_gapend += delta; 124 | 125 | #ifdef GAP_BUFFER_TIDY 126 | std::memset(pdata + this->_gapstart, 0x00, this->gapLength()); 127 | #endif 128 | } 129 | 130 | void GapBuffer::expandGap(integer_t cap) 131 | { 132 | if(cap <= this->gapLength()) 133 | return; 134 | 135 | if(this->_gapminlength < cap) 136 | this->_gapminlength = cap * 2; 137 | 138 | sinteger_t delta = this->_gapminlength - this->gapLength(); 139 | this->_buffer.reserve(this->_buffer.length() + delta); 140 | 141 | this->_gapend = this->_gapstart + this->_gapminlength; 142 | 143 | #ifdef GAP_BUFFER_TIDY 144 | this->_buffer.insert(this->_gapstart, QByteArray(delta, Qt::Uninitialized)); 145 | #else 146 | this->_buffer.insert(this->_gapstart, QByteArray(delta, char(0))); 147 | #endif 148 | } 149 | 150 | void GapBuffer::init(QIODevice *device) 151 | { 152 | if(!device->isOpen()) 153 | device->open(QIODevice::ReadWrite); 154 | 155 | #ifdef GAP_BUFFER_TIDY 156 | this->_buffer.append(QByteArray(device->size() + this->gapLength(), '\0')); 157 | #else 158 | this->_buffer.resize(device->size() + this->gapLength()); 159 | #endif 160 | 161 | device->read(this->_buffer.data() + this->gapLength(), device->size()); 162 | } 163 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/gapbuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef GAPBUFFER_H 2 | #define GAPBUFFER_H 3 | 4 | #include 5 | #include 6 | 7 | //#define GAP_BUFFER_TIDY 8 | 9 | typedef int64_t sinteger_t; 10 | typedef uint64_t integer_t; 11 | 12 | class GapBuffer 13 | { 14 | public: 15 | GapBuffer(); 16 | GapBuffer(QIODevice* device); 17 | ~GapBuffer(); 18 | 19 | public: 20 | void insert(integer_t index, const QByteArray& data); 21 | void replace(integer_t index, const QByteArray& data); 22 | void remove(integer_t index, integer_t len); 23 | char at(integer_t index) const; 24 | QByteArray read(integer_t index, integer_t len = 0) const; 25 | QByteArray toByteArray() const; 26 | integer_t length() const; 27 | 28 | private: 29 | integer_t gapLength() const; 30 | void moveGap(integer_t index, integer_t len); 31 | void expandGap(integer_t cap); 32 | void init(QIODevice* device); 33 | 34 | private: 35 | integer_t _gapstart, _gapend, _gapminlength; 36 | QByteArray _buffer; 37 | }; 38 | 39 | #endif // GAPBUFFER_H 40 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/metadata/qhexmetadata.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexmetadata.h" 2 | #include 3 | #include 4 | 5 | typedef QMutableHashIterator MetadataIterator; 6 | 7 | #define RangeContains(offset, it) (offset >= it.key() && offset <= it.value()) 8 | 9 | static void removeMetadata(MetadataMap& metadata, std::function cb) 10 | { 11 | MetadataIterator it(metadata); 12 | 13 | while(it.hasNext()) 14 | { 15 | it.next(); 16 | sinteger_t i = 0; 17 | MetadataList& values = metadata[it.key()]; 18 | 19 | while(i < values.length()) 20 | { 21 | if(cb(values[i])) 22 | values.removeAt(i); 23 | else 24 | i++; 25 | } 26 | } 27 | } 28 | 29 | QHexMetadata::QHexMetadata(QObject *parent) : QObject(parent), _bulkmetadata(false) 30 | { 31 | 32 | } 33 | 34 | void QHexMetadata::insert(QHexMetadataItem *metaitem) 35 | { 36 | if(!this->_metadata.contains(metaitem->startOffset())) 37 | { 38 | this->_metadata[metaitem->startOffset()] = MetadataList(); 39 | this->_ranges[metaitem->startOffset()] = 0; 40 | } 41 | 42 | this->_metadata[metaitem->startOffset()].append(metaitem); 43 | this->_ranges[metaitem->startOffset()] = qMax(this->_ranges[metaitem->startOffset()], metaitem->endOffset()); 44 | 45 | if(!this->_bulkmetadata) 46 | emit metadataChanged(); 47 | } 48 | 49 | void QHexMetadata::beginMetadata() 50 | { 51 | this->_bulkmetadata = true; 52 | } 53 | 54 | void QHexMetadata::endMetadata() 55 | { 56 | this->_bulkmetadata = false; 57 | emit metadataChanged(); 58 | } 59 | 60 | void QHexMetadata::clearHighlighting() 61 | { 62 | if(this->_metadata.isEmpty()) 63 | return; 64 | 65 | removeMetadata(this->_metadata, [](QHexMetadataItem* metaitem) -> bool { 66 | if(metaitem->hasComment()) { 67 | metaitem->clearColors(); 68 | return false; 69 | } 70 | 71 | return true; 72 | }); 73 | 74 | if(!this->_bulkmetadata) 75 | emit metadataChanged(); 76 | } 77 | 78 | void QHexMetadata::clearComments() 79 | { 80 | if(this->_metadata.isEmpty()) 81 | return; 82 | 83 | removeMetadata(this->_metadata, [this](QHexMetadataItem* metaitem) -> bool { 84 | bool doremove = false; 85 | 86 | if(metaitem->hasForeColor() || metaitem->hasBackColor()) 87 | metaitem->clearComment(); 88 | else 89 | doremove = true; 90 | 91 | return doremove; 92 | }); 93 | 94 | if(!this->_bulkmetadata) 95 | emit metadataChanged(); 96 | } 97 | 98 | MetadataList QHexMetadata::fromOffset(integer_t offset) const 99 | { 100 | if(this->_ranges.isEmpty()) 101 | return MetadataList(); 102 | 103 | MetadataList metadata; 104 | 105 | for(RangeMap::const_iterator it = this->_ranges.begin(); it != this->_ranges.end(); it++) 106 | { 107 | if(it.key() > offset) 108 | break; 109 | 110 | if(!RangeContains(offset, it)) 111 | continue; 112 | 113 | metadata += this->_metadata[it.key()]; 114 | } 115 | 116 | return metadata; 117 | } 118 | 119 | QString QHexMetadata::commentString(integer_t offset) const 120 | { 121 | const QHexMetadataItem* metadata = this->comment(offset); 122 | 123 | if(metadata) 124 | return metadata->comment(); 125 | 126 | return QString(); 127 | } 128 | 129 | const QHexMetadataItem *QHexMetadata::comment(integer_t offset) const 130 | { 131 | MetadataList metalist = this->fromOffset(offset); 132 | 133 | for(MetadataList::const_reverse_iterator it = metalist.crbegin(); it != metalist.crend(); it++) 134 | { 135 | if((*it)->hasComment()) 136 | return *it; 137 | } 138 | 139 | return NULL; 140 | } 141 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/metadata/qhexmetadata.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXMETADATA_H 2 | #define QHEXMETADATA_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "qhexmetadataitem.h" 9 | 10 | typedef QList MetadataList; 11 | typedef QHash MetadataMap; 12 | 13 | class QHexMetadata : public QObject 14 | { 15 | Q_OBJECT 16 | 17 | private: 18 | typedef QMap RangeMap; 19 | typedef QPair RangeIterators; 20 | 21 | public: 22 | explicit QHexMetadata(QObject *parent = 0); 23 | void insert(QHexMetadataItem* metaitem); 24 | void beginMetadata(); 25 | void endMetadata(); 26 | void clearHighlighting(); 27 | void clearComments(); 28 | MetadataList fromOffset(integer_t offset) const; 29 | QString commentString(integer_t offset) const; 30 | 31 | private: 32 | const QHexMetadataItem *comment(integer_t offset) const; 33 | 34 | signals: 35 | void metadataChanged(); 36 | 37 | private: 38 | RangeMap _ranges; 39 | RangeIterators _lastrange; 40 | MetadataMap _metadata; 41 | bool _bulkmetadata; 42 | }; 43 | 44 | #endif // QHEXMETADATA_H 45 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/metadata/qhexmetadataitem.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexmetadataitem.h" 2 | 3 | QHexMetadataItem::QHexMetadataItem(integer_t startoffset, integer_t endoffset, QObject *parent) : QObject(parent), _startoffset(startoffset), _endoffset(endoffset) 4 | { 5 | 6 | } 7 | 8 | integer_t QHexMetadataItem::startOffset() const 9 | { 10 | return this->_startoffset; 11 | } 12 | 13 | integer_t QHexMetadataItem::endOffset() const 14 | { 15 | return this->_endoffset; 16 | } 17 | 18 | bool QHexMetadataItem::contains(integer_t offset) const 19 | { 20 | return (offset >= this->_startoffset) && (offset <= this->_endoffset); 21 | } 22 | 23 | bool QHexMetadataItem::hasBackColor() const 24 | { 25 | return this->_backcolor.isValid(); 26 | } 27 | 28 | bool QHexMetadataItem::hasForeColor() const 29 | { 30 | return this->_forecolor.isValid(); 31 | } 32 | 33 | bool QHexMetadataItem::hasComment() const 34 | { 35 | return !this->_comment.isEmpty(); 36 | } 37 | 38 | const QColor& QHexMetadataItem::backColor() const 39 | { 40 | return this->_backcolor; 41 | } 42 | 43 | const QColor &QHexMetadataItem::foreColor() const 44 | { 45 | return this->_forecolor; 46 | } 47 | 48 | const QString &QHexMetadataItem::comment() const 49 | { 50 | return this->_comment; 51 | } 52 | 53 | void QHexMetadataItem::setBackColor(const QColor &c) 54 | { 55 | this->_backcolor = c; 56 | } 57 | 58 | void QHexMetadataItem::setForeColor(const QColor &c) 59 | { 60 | this->_forecolor = c; 61 | } 62 | 63 | void QHexMetadataItem::setComment(const QString &s) 64 | { 65 | this->_comment = s; 66 | } 67 | 68 | void QHexMetadataItem::clearComment() 69 | { 70 | this->_comment.clear(); 71 | } 72 | 73 | void QHexMetadataItem::clearColors() 74 | { 75 | this->_backcolor = QColor(); 76 | this->_forecolor = QColor(); 77 | } 78 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/metadata/qhexmetadataitem.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXMETADATAITEM_H 2 | #define QHEXMETADATAITEM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../gapbuffer.h" 8 | 9 | class QHexMetadataItem : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit QHexMetadataItem(integer_t startoffset, integer_t endoffset, QObject *parent = 0); 15 | integer_t startOffset() const; 16 | integer_t endOffset() const; 17 | bool contains(integer_t offset) const; 18 | bool hasBackColor() const; 19 | bool hasForeColor() const; 20 | bool hasComment() const; 21 | const QColor& backColor() const; 22 | const QColor& foreColor() const; 23 | const QString& comment() const; 24 | void setBackColor(const QColor& c); 25 | void setForeColor(const QColor& c); 26 | void setComment(const QString& s); 27 | void clearComment(); 28 | void clearColors(); 29 | 30 | private: 31 | integer_t _startoffset, _endoffset; 32 | QColor _backcolor, _forecolor; 33 | QString _comment; 34 | }; 35 | 36 | #endif // QHEXMETADATAITEM_H 37 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/qhexcursor.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexcursor.h" 2 | #include "qhexdocument.h" 3 | #include 4 | #include 5 | 6 | #define currentDocument static_cast(this->parent()) 7 | //#define currentContainer static_cast(currentDocument->parent()) 8 | 9 | const int QHexCursor::CURSOR_BLINK_INTERVAL = 500; // 5ms 10 | 11 | QHexCursor::QHexCursor(QObject *parent) : QObject(parent), _selectedpart(QHexCursor::HexPart), _insertionmode(QHexCursor::OverwriteMode) 12 | { 13 | this->_cursorx = this->_cursory = 0; 14 | this->_selectionstart = this->_offset = this->_nibbleindex = 0; 15 | this->_timerid = this->startTimer(QHexCursor::CURSOR_BLINK_INTERVAL); 16 | } 17 | 18 | QHexCursor::~QHexCursor() 19 | { 20 | this->killTimer(this->_timerid); 21 | } 22 | 23 | QPoint QHexCursor::position() const 24 | { 25 | return QPoint(this->_cursorx, this->_cursory); 26 | } 27 | 28 | sinteger_t QHexCursor::cursorX() const 29 | { 30 | return this->_cursorx; 31 | } 32 | 33 | sinteger_t QHexCursor::cursorY() const 34 | { 35 | return this->_cursory; 36 | } 37 | 38 | integer_t QHexCursor::offset() const 39 | { 40 | return this->_offset; 41 | } 42 | 43 | integer_t QHexCursor::nibbleIndex() const 44 | { 45 | return this->_nibbleindex; 46 | } 47 | 48 | integer_t QHexCursor::selectionStart() const 49 | { 50 | return qMin(this->_offset, this->_selectionstart); 51 | } 52 | 53 | integer_t QHexCursor::selectionEnd() const 54 | { 55 | return qMax(this->_offset, this->_selectionstart); 56 | } 57 | 58 | integer_t QHexCursor::selectionLength() const 59 | { 60 | return this->selectionEnd() - this->selectionStart(); 61 | } 62 | 63 | QHexCursor::SelectedPart QHexCursor::selectedPart() const 64 | { 65 | return this->_selectedpart; 66 | } 67 | 68 | QHexCursor::InsertionMode QHexCursor::insertionMode() const 69 | { 70 | return this->_insertionmode; 71 | } 72 | 73 | bool QHexCursor::isAddressPartSelected() const 74 | { 75 | return this->_selectedpart == QHexCursor::AddressPart; 76 | } 77 | 78 | bool QHexCursor::isHexPartSelected() const 79 | { 80 | return this->_selectedpart == QHexCursor::HexPart; 81 | } 82 | 83 | bool QHexCursor::isAsciiPartSelected() const 84 | { 85 | return this->_selectedpart == QHexCursor::AsciiPart; 86 | } 87 | 88 | bool QHexCursor::isInsertMode() const 89 | { 90 | return this->_insertionmode == QHexCursor::InsertMode; 91 | } 92 | 93 | bool QHexCursor::isOverwriteMode() const 94 | { 95 | return this->_insertionmode == QHexCursor::OverwriteMode; 96 | } 97 | 98 | bool QHexCursor::hasSelection() const 99 | { 100 | return this->_offset != this->_selectionstart; 101 | } 102 | 103 | bool QHexCursor::blinking() const 104 | { 105 | return this->_blink; 106 | } 107 | 108 | bool QHexCursor::isSelected(integer_t offset) const 109 | { 110 | if(this->_offset == this->_selectionstart) 111 | return false; 112 | 113 | return (offset >= this->selectionStart()) && (offset < this->selectionEnd()); 114 | } 115 | 116 | void QHexCursor::selectStart() 117 | { 118 | this->setOffset(0); 119 | } 120 | 121 | void QHexCursor::selectEnd() 122 | { 123 | this->setOffset(currentDocument->length()); 124 | } 125 | 126 | void QHexCursor::selectAll() 127 | { 128 | this->setSelection(0, currentDocument->length()); 129 | } 130 | 131 | void QHexCursor::setPosition(sinteger_t x, sinteger_t y) 132 | { 133 | if((this->_cursorx == x) && (this->_cursory == y)) 134 | return; 135 | 136 | this->_cursorx = x; 137 | this->_cursory = y; 138 | emit positionChanged(); 139 | } 140 | 141 | void QHexCursor::setOffset(integer_t offset) 142 | { 143 | this->setOffset(offset, 0); 144 | } 145 | 146 | void QHexCursor::setOffset(integer_t offset, integer_t nibbleindex) 147 | { 148 | offset = qMin(offset, currentDocument->length()); // Check EOF 149 | this->_selectionstart = offset; 150 | this->_nibbleindex = nibbleindex; 151 | 152 | this->setSelectionEnd(offset); 153 | } 154 | 155 | void QHexCursor::setSelectionEnd(integer_t offset) 156 | { 157 | offset = qMin(offset, currentDocument->length()); // Check EOF 158 | this->_offset = offset; 159 | 160 | emit selectionChanged(); 161 | emit offsetChanged(); 162 | } 163 | 164 | void QHexCursor::setSelection(integer_t startoffset, integer_t endoffset) 165 | { 166 | this->setOffset(startoffset); 167 | this->setSelectionEnd(endoffset); 168 | } 169 | 170 | void QHexCursor::setSelectionRange(integer_t startoffset, integer_t length) 171 | { 172 | this->setSelection(startoffset, startoffset + length); 173 | } 174 | 175 | void QHexCursor::setSelectedPart(QHexCursor::SelectedPart sp) 176 | { 177 | if(sp == this->_selectedpart) 178 | return; 179 | 180 | this->_selectedpart = sp; 181 | emit selectedPartChanged(); 182 | } 183 | 184 | void QHexCursor::clearSelection() 185 | { 186 | if(this->_selectionstart == this->_offset) 187 | return; 188 | 189 | this->_selectionstart = this->_offset; 190 | emit selectionChanged(); 191 | } 192 | 193 | bool QHexCursor::removeSelection() 194 | { 195 | if(!this->hasSelection()) 196 | return false; 197 | 198 | currentDocument->remove(this->selectionStart(), this->selectionLength()); 199 | this->clearSelection(); 200 | return true; 201 | } 202 | 203 | void QHexCursor::moveOffset(sinteger_t c, bool bynibble) 204 | { 205 | if(!c) 206 | return; 207 | 208 | if(qAbs(c) > 1) 209 | bynibble = false; 210 | 211 | integer_t nindex = 0; 212 | 213 | if(bynibble) 214 | { 215 | if(!this->_nibbleindex) 216 | { 217 | if(c > 0) 218 | c = 0; 219 | 220 | nindex = 1; 221 | } 222 | else 223 | { 224 | if(c < 0) 225 | c = 0; 226 | 227 | nindex = 0; 228 | } 229 | } 230 | 231 | integer_t offset = this->_offset + c; 232 | 233 | if(offset >= currentDocument->length()) 234 | offset = c > 0 ? currentDocument->length() : 0; 235 | 236 | this->setOffset(offset, nindex); 237 | } 238 | 239 | void QHexCursor::moveSelection(sinteger_t c) 240 | { 241 | if(!c) 242 | return; 243 | 244 | integer_t offset = this->_offset + c; 245 | 246 | if(offset >= currentDocument->length()) 247 | offset = c > 0 ? currentDocument->length() : 0; 248 | 249 | this->setSelectionEnd(offset); 250 | } 251 | 252 | void QHexCursor::blink(bool b) 253 | { 254 | this->_blink = b; 255 | emit blinkChanged(); 256 | } 257 | 258 | void QHexCursor::switchMode() 259 | { 260 | if(this->_insertionmode == QHexCursor::OverwriteMode) 261 | this->_insertionmode = QHexCursor::InsertMode; 262 | else 263 | this->_insertionmode = QHexCursor::OverwriteMode; 264 | 265 | emit insertionModeChanged(); 266 | } 267 | 268 | void QHexCursor::timerEvent(QTimerEvent *event) 269 | { 270 | Q_UNUSED(event); 271 | 272 | this->_blink = !this->_blink; 273 | emit blinkChanged(); 274 | } 275 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/qhexcursor.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXCURSOR_H 2 | #define QHEXCURSOR_H 3 | 4 | #include 5 | #include "gapbuffer.h" 6 | 7 | class QHexCursor : public QObject 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | enum SelectedPart { AddressPart, HexPart, AsciiPart }; 13 | enum InsertionMode { OverwriteMode, InsertMode }; 14 | 15 | public: 16 | explicit QHexCursor(QObject *parent = 0); 17 | ~QHexCursor(); 18 | QPoint position() const; 19 | sinteger_t cursorX() const; 20 | sinteger_t cursorY() const; 21 | integer_t offset() const; 22 | integer_t nibbleIndex() const; 23 | integer_t selectionStart() const; 24 | integer_t selectionEnd() const; 25 | integer_t selectionLength() const; 26 | SelectedPart selectedPart() const; 27 | InsertionMode insertionMode() const; 28 | bool isAddressPartSelected() const; 29 | bool isHexPartSelected() const; 30 | bool isAsciiPartSelected() const; 31 | bool isInsertMode() const; 32 | bool isOverwriteMode() const; 33 | bool hasSelection() const; 34 | bool blinking() const; 35 | bool isSelected(integer_t offset) const; 36 | void selectStart(); 37 | void selectEnd(); 38 | void selectAll(); 39 | void setPosition(sinteger_t x, sinteger_t y); 40 | void setOffset(integer_t offset); 41 | void setOffset(integer_t offset, integer_t nibbleindex); 42 | void setSelectionEnd(integer_t offset); 43 | void setSelection(integer_t startoffset, integer_t endoffset); 44 | void setSelectionRange(integer_t startoffset, integer_t length); 45 | void setSelectedPart(SelectedPart sp); 46 | void clearSelection(); 47 | bool removeSelection(); 48 | void moveOffset(sinteger_t c, bool bynibble = false); 49 | void moveSelection(sinteger_t c); 50 | void blink(bool b); 51 | void switchMode(); 52 | 53 | protected: 54 | virtual void timerEvent(QTimerEvent *event); 55 | 56 | signals: 57 | void blinkChanged(); 58 | void positionChanged(); 59 | void offsetChanged(); 60 | void selectionChanged(); 61 | void selectedPartChanged(); 62 | void insertionModeChanged(); 63 | 64 | private: 65 | static const int CURSOR_BLINK_INTERVAL; // 5ms 66 | SelectedPart _selectedpart; 67 | InsertionMode _insertionmode; 68 | sinteger_t _cursorx, _cursory; 69 | integer_t _selectionstart, _offset, _nibbleindex; 70 | int _timerid; 71 | bool _blink; 72 | }; 73 | 74 | #endif // QHEXCURSOR_H 75 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/qhexdocument.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexdocument.h" 2 | #include "commands/insertcommand.h" 3 | #include "commands/removecommand.h" 4 | #include "commands/replacecommand.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | QHexDocument::QHexDocument(QIODevice *device, QObject *parent): QObject(parent), _baseaddress(0) 12 | { 13 | this->_gapbuffer = new GapBuffer(device); 14 | this->_cursor = new QHexCursor(this); 15 | this->_metadata = new QHexMetadata(this); 16 | 17 | connect(this->_metadata, &QHexMetadata::metadataChanged, this, &QHexDocument::documentChanged); 18 | connect(&this->_undostack, &QUndoStack::canUndoChanged, this, &QHexDocument::canUndoChanged); 19 | connect(&this->_undostack, &QUndoStack::canRedoChanged, this, &QHexDocument::canRedoChanged); 20 | } 21 | 22 | QHexDocument::~QHexDocument() 23 | { 24 | delete this->_gapbuffer; 25 | this->_gapbuffer = NULL; 26 | } 27 | 28 | QHexCursor *QHexDocument::cursor() const 29 | { 30 | return this->_cursor; 31 | } 32 | 33 | QHexMetadata *QHexDocument::metadata() const 34 | { 35 | return this->_metadata; 36 | } 37 | 38 | integer_t QHexDocument::length() const 39 | { 40 | return this->_gapbuffer->length(); 41 | } 42 | 43 | integer_t QHexDocument::baseAddress() const 44 | { 45 | return this->_baseaddress; 46 | } 47 | 48 | bool QHexDocument::canUndo() const 49 | { 50 | return this->_undostack.canUndo(); 51 | } 52 | 53 | bool QHexDocument::canRedo() const 54 | { 55 | return this->_undostack.canRedo(); 56 | } 57 | 58 | QByteArray QHexDocument::read(integer_t offset, integer_t len) 59 | { 60 | return this->_gapbuffer->read(offset, len); 61 | } 62 | 63 | QByteArray QHexDocument::selectedBytes() const 64 | { 65 | if(!this->_cursor->hasSelection()) 66 | return QByteArray(); 67 | 68 | return this->_gapbuffer->read(this->_cursor->selectionStart(), this->_cursor->selectionEnd()); 69 | } 70 | 71 | char QHexDocument::at(integer_t offset) const 72 | { 73 | return this->_gapbuffer->at(offset); 74 | } 75 | 76 | void QHexDocument::setBaseAddress(integer_t baseaddress) 77 | { 78 | if(this->_baseaddress == baseaddress) 79 | return; 80 | 81 | this->_baseaddress = baseaddress; 82 | emit baseAddressChanged(); 83 | } 84 | 85 | QHexDocument *QHexDocument::fromDevice(QIODevice *iodevice) 86 | { 87 | if(!iodevice->isOpen()) 88 | iodevice->open(QFile::ReadWrite); 89 | 90 | return new QHexDocument(iodevice); 91 | } 92 | 93 | QHexDocument *QHexDocument::fromFile(QString filename) 94 | { 95 | QFileInfo fi(filename); 96 | QFile* f = new QFile(filename); 97 | 98 | if(fi.isWritable()) 99 | f->open(QFile::ReadWrite); 100 | else 101 | f->open(QFile::ReadOnly); 102 | 103 | QHexDocument* document = QHexDocument::fromDevice(f); 104 | f->setParent(document); 105 | return document; 106 | } 107 | 108 | QHexDocument *QHexDocument::fromMemory(const QByteArray &ba) 109 | { 110 | QBuffer* b = new QBuffer(); 111 | b->setData(ba); 112 | b->open(QFile::ReadOnly); 113 | 114 | QHexDocument* document = QHexDocument::fromDevice(b); 115 | b->setParent(document); 116 | return document; 117 | } 118 | 119 | void QHexDocument::undo() 120 | { 121 | this->_undostack.undo(); 122 | emit documentChanged(); 123 | } 124 | 125 | void QHexDocument::redo() 126 | { 127 | this->_undostack.redo(); 128 | emit documentChanged(); 129 | } 130 | 131 | void QHexDocument::cut() 132 | { 133 | if(!this->_cursor->hasSelection()) 134 | return; 135 | 136 | QClipboard* c = qApp->clipboard(); 137 | c->setText(QString(this->selectedBytes())); 138 | this->_cursor->removeSelection(); 139 | } 140 | 141 | void QHexDocument::copy() 142 | { 143 | if(!this->_cursor->hasSelection()) 144 | return; 145 | 146 | QClipboard* c = qApp->clipboard(); 147 | c->setText(QString(this->selectedBytes())); 148 | } 149 | 150 | void QHexDocument::paste() 151 | { 152 | QClipboard* c = qApp->clipboard(); 153 | QByteArray data = c->text().toUtf8(); 154 | 155 | if(data.isEmpty()) 156 | return; 157 | 158 | this->_cursor->removeSelection(); 159 | 160 | if(this->_cursor->isInsertMode()) 161 | this->insert(this->_cursor->offset(), data); 162 | else 163 | this->replace(this->_cursor->offset(), data); 164 | 165 | this->_cursor->moveOffset(data.length()); 166 | } 167 | 168 | void QHexDocument::insert(integer_t offset, uchar b) 169 | { 170 | this->insert(offset, QByteArray(1, b)); 171 | } 172 | 173 | void QHexDocument::replace(integer_t offset, uchar b) 174 | { 175 | this->replace(offset, QByteArray(1, b)); 176 | } 177 | 178 | void QHexDocument::insert(integer_t offset, const QByteArray &data) 179 | { 180 | this->_undostack.push(new InsertCommand(this->_gapbuffer, offset, data)); 181 | emit documentChanged(); 182 | } 183 | 184 | void QHexDocument::replace(integer_t offset, const QByteArray &data) 185 | { 186 | this->_undostack.push(new ReplaceCommand(this->_gapbuffer, offset, data)); 187 | emit documentChanged(); 188 | } 189 | 190 | void QHexDocument::remove(integer_t offset, integer_t len) 191 | { 192 | this->_undostack.push(new RemoveCommand(this->_gapbuffer, offset, len)); 193 | emit documentChanged(); 194 | } 195 | 196 | void QHexDocument::highlightFore(integer_t startoffset, integer_t endoffset, const QColor &c) 197 | { 198 | if((startoffset == endoffset) || !c.isValid()) 199 | return; 200 | 201 | QHexMetadataItem* metaitem = new QHexMetadataItem(startoffset, endoffset, this->_metadata); 202 | metaitem->setForeColor(c); 203 | this->_metadata->insert(metaitem); 204 | } 205 | 206 | void QHexDocument::highlightBack(integer_t startoffset, integer_t endoffset, const QColor &c) 207 | { 208 | if((startoffset == endoffset) || !c.isValid()) 209 | return; 210 | 211 | QHexMetadataItem* metaitem = new QHexMetadataItem(startoffset, endoffset, this->_metadata); 212 | metaitem->setBackColor(c); 213 | this->_metadata->insert(metaitem); 214 | } 215 | 216 | void QHexDocument::highlightForeRange(integer_t offset, integer_t length, const QColor &c) 217 | { 218 | this->highlightFore(offset, offset + length - 1, c); 219 | } 220 | 221 | void QHexDocument::highlightBackRange(integer_t offset, integer_t length, const QColor &c) 222 | { 223 | this->highlightBack(offset, offset + length - 1, c); 224 | } 225 | 226 | void QHexDocument::comment(integer_t startoffset, integer_t endoffset, const QString &s) 227 | { 228 | if((startoffset == endoffset) || s.isEmpty()) 229 | return; 230 | 231 | QHexMetadataItem* metaitem = new QHexMetadataItem(startoffset, endoffset, this->_metadata); 232 | metaitem->setComment(s); 233 | this->_metadata->insert(metaitem); 234 | } 235 | 236 | void QHexDocument::commentRange(integer_t offset, integer_t length, const QString &s) 237 | { 238 | this->comment(offset, offset + length - 1, s); 239 | } 240 | 241 | void QHexDocument::clearHighlighting() 242 | { 243 | this->_metadata->clearHighlighting(); 244 | } 245 | 246 | void QHexDocument::clearComments() 247 | { 248 | this->_metadata->clearComments(); 249 | } 250 | 251 | void QHexDocument::clearMetadata() 252 | { 253 | this->beginMetadata(); 254 | this->_metadata->clearComments(); 255 | this->_metadata->clearHighlighting(); 256 | this->endMetadata(); 257 | } 258 | 259 | void QHexDocument::beginMetadata() 260 | { 261 | this->_metadata->beginMetadata(); 262 | } 263 | 264 | void QHexDocument::endMetadata() 265 | { 266 | this->_metadata->endMetadata(); 267 | } 268 | 269 | QByteArray QHexDocument::read(integer_t offset, integer_t len) const 270 | { 271 | return this->_gapbuffer->read(offset, len); 272 | } 273 | 274 | bool QHexDocument::saveTo(QIODevice *device) 275 | { 276 | if(!device->isWritable()) 277 | return false; 278 | 279 | device->write(this->_gapbuffer->toByteArray()); 280 | return true; 281 | } 282 | 283 | bool QHexDocument::isEmpty() const 284 | { 285 | return this->_gapbuffer->length() <= 0; 286 | } 287 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/qhexdocument.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXDOCUMENT_H 2 | #define QHEXDOCUMENT_H 3 | 4 | #include 5 | #include 6 | #include "gapbuffer.h" 7 | #include "metadata/qhexmetadata.h" 8 | #include "qhexcursor.h" 9 | 10 | class QHexDocument: public QObject 11 | { 12 | Q_OBJECT 13 | 14 | private: 15 | typedef QHash CommentHash; 16 | 17 | private: 18 | explicit QHexDocument(QIODevice* device, QObject *parent = 0); 19 | ~QHexDocument(); 20 | 21 | public: 22 | QHexCursor* cursor() const; 23 | QHexMetadata* metadata() const; 24 | integer_t length() const; 25 | integer_t baseAddress() const; 26 | bool canUndo() const; 27 | bool canRedo() const; 28 | QByteArray read(integer_t offset, integer_t len = 0); 29 | QByteArray selectedBytes() const; 30 | char at(integer_t offset) const; 31 | void setBaseAddress(integer_t baseaddress); 32 | 33 | public: 34 | static QHexDocument* fromDevice(QIODevice* iodevice); 35 | static QHexDocument* fromFile(QString filename); 36 | static QHexDocument* fromMemory(const QByteArray& ba); 37 | 38 | public slots: 39 | void undo(); 40 | void redo(); 41 | void cut(); 42 | void copy(); 43 | void paste(); 44 | void insert(integer_t offset, uchar b); 45 | void replace(integer_t offset, uchar b); 46 | void insert(integer_t offset, const QByteArray& data); 47 | void replace(integer_t offset, const QByteArray& data); 48 | void remove(integer_t offset, integer_t len); 49 | void highlightFore(integer_t startoffset, integer_t endoffset, const QColor &c); 50 | void highlightBack(integer_t startoffset, integer_t endoffset, const QColor &c); 51 | void highlightForeRange(integer_t offset, integer_t length, const QColor &c); 52 | void highlightBackRange(integer_t offset, integer_t length, const QColor &c); 53 | void comment(integer_t startoffset, integer_t endoffset, const QString& s); 54 | void commentRange(integer_t offset, integer_t length, const QString& s); 55 | void clearHighlighting(); 56 | void clearComments(); 57 | void clearMetadata(); 58 | void beginMetadata(); 59 | void endMetadata(); 60 | QByteArray read(integer_t offset, integer_t len) const; 61 | bool saveTo(QIODevice* device); 62 | bool isEmpty() const; 63 | 64 | signals: 65 | void canUndoChanged(); 66 | void canRedoChanged(); 67 | void documentChanged(); 68 | void baseAddressChanged(); 69 | 70 | private: 71 | CommentHash _comments; 72 | QUndoStack _undostack; 73 | GapBuffer* _gapbuffer; 74 | QHexCursor* _cursor; 75 | QHexMetadata* _metadata; 76 | integer_t _baseaddress; 77 | }; 78 | 79 | #endif // QHEXEDITDATA_H 80 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/qhextheme.cpp: -------------------------------------------------------------------------------- 1 | #include "qhextheme.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | QHexTheme::QHexTheme(QObject *parent): QObject(parent) 8 | { 9 | QWidget* container = static_cast(parent); 10 | 11 | container->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); 12 | container->setBackgroundRole(QPalette::Base); 13 | 14 | this->_selectedcursor = QColor(Qt::lightGray); 15 | this->_addressbackground = QColor(0xF0, 0xF0, 0xFE); 16 | this->_addressforeground = QColor(Qt::darkBlue); 17 | this->_alternateaddressforeground = QColor(Qt::red); 18 | this->_alternatelinecolor = QColor(0xF0, 0xF0, 0xFE); 19 | this->_linecolor = QColor(0xFF, 0xFF, 0xA0); 20 | } 21 | 22 | QColor QHexTheme::baseColor() const 23 | { 24 | return this->_basecolor; 25 | } 26 | 27 | QColor QHexTheme::selectedCursor() const 28 | { 29 | return this->_selectedcursor; 30 | } 31 | 32 | QColor QHexTheme::addressBackground() const 33 | { 34 | return this->_addressbackground; 35 | } 36 | 37 | QColor QHexTheme::addressForeground() const 38 | { 39 | return this->_addressforeground; 40 | } 41 | 42 | QColor QHexTheme::alternateAddressForeground() const 43 | { 44 | return this->_alternateaddressforeground; 45 | } 46 | 47 | QColor QHexTheme::alternateLineColor() const 48 | { 49 | return this->_alternatelinecolor; 50 | } 51 | 52 | QColor QHexTheme::lineColor() const 53 | { 54 | return this->_linecolor; 55 | } 56 | 57 | void QHexTheme::setBaseColor(const QColor &color) 58 | { 59 | if(this->_basecolor == color) 60 | return; 61 | 62 | this->_basecolor = color; 63 | emit themeChanged(); 64 | } 65 | 66 | void QHexTheme::setSelectedCursor(const QColor &color) 67 | { 68 | if(this->_selectedcursor == color) 69 | return; 70 | 71 | this->_selectedcursor = color; 72 | emit themeChanged(); 73 | } 74 | 75 | void QHexTheme::setAddressBackground(const QColor &color) 76 | { 77 | if(this->_addressbackground == color) 78 | return; 79 | 80 | this->_addressbackground = color; 81 | emit themeChanged(); 82 | } 83 | 84 | void QHexTheme::setAddressForeground(const QColor &color) 85 | { 86 | if(this->_addressforeground == color) 87 | return; 88 | 89 | this->_addressforeground = color; 90 | emit themeChanged(); 91 | } 92 | 93 | void QHexTheme::setAlternateAddressForeground(const QColor &color) 94 | { 95 | if(this->_alternateaddressforeground == color) 96 | return; 97 | 98 | this->_alternateaddressforeground = color; 99 | emit themeChanged(); 100 | } 101 | 102 | void QHexTheme::setAlternateLineColor(const QColor &color) 103 | { 104 | if(this->_alternatelinecolor == color) 105 | return; 106 | 107 | this->_alternatelinecolor = color; 108 | emit themeChanged(); 109 | } 110 | 111 | void QHexTheme::setLineColor(const QColor &color) 112 | { 113 | if(this->_linecolor == color) 114 | return; 115 | 116 | this->_linecolor = color; 117 | emit themeChanged(); 118 | } 119 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/document/qhextheme.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXTHEME_H 2 | #define QHEXTHEME_H 3 | 4 | #include 5 | #include 6 | 7 | class QHexTheme: public QObject 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | QHexTheme(QObject* parent = 0); 13 | QColor baseColor() const; 14 | QColor selectedCursor() const; 15 | QColor addressBackground() const; 16 | QColor addressForeground() const; 17 | QColor alternateAddressForeground() const; 18 | QColor alternateLineColor() const; 19 | QColor lineColor() const; 20 | 21 | public: 22 | void setBaseColor(const QColor& color); 23 | void setSelectedCursor(const QColor& color); 24 | void setAddressBackground(const QColor& color); 25 | void setAddressForeground(const QColor& color); 26 | void setAlternateAddressForeground(const QColor& color); 27 | void setAlternateLineColor(const QColor& color); 28 | void setLineColor(const QColor& color); 29 | 30 | signals: 31 | void themeChanged(); 32 | 33 | private: 34 | QColor _basecolor; 35 | QColor _selectedcursor; 36 | QColor _addressbackground; 37 | QColor _addressforeground; 38 | QColor _alternateaddressforeground; 39 | QColor _alternatelinecolor; 40 | QColor _linecolor; 41 | }; 42 | 43 | #endif // QHEXTHEME_H 44 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/paint/qhexmetrics.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexmetrics.h" 2 | 3 | const sinteger_t QHexMetrics::BYTES_PER_LINE = 0x10; 4 | const sinteger_t QHexMetrics::DEFAULT_ADDRESS_WIDTH = 8; 5 | 6 | #define currentContainer static_cast(this->parent()) 7 | 8 | QHexMetrics::QHexMetrics(QScrollBar *vscrollbar, QWidget *parent): QObject(parent), _vscrollbar(vscrollbar), _document(NULL) 9 | { 10 | this->_addresswidth = 0; 11 | this->_charwidth = this->_charheight = 0; 12 | this->_xposascii = this->_xposhex = this->_xposend = 0; 13 | } 14 | 15 | QHexDocument *QHexMetrics::document() const 16 | { 17 | return this->_document; 18 | } 19 | 20 | QScrollBar *QHexMetrics::verticalScrollBar() const 21 | { 22 | return this->_vscrollbar; 23 | } 24 | 25 | QSize QHexMetrics::charSize() const 26 | { 27 | return QSize(this->_charwidth, this->_charheight); 28 | } 29 | 30 | integer_t QHexMetrics::visibleStartOffset() const 31 | { 32 | return qMin(static_cast(this->_vscrollbar->sliderPosition() * QHexMetrics::BYTES_PER_LINE), this->_document->length()); 33 | } 34 | 35 | integer_t QHexMetrics::visibleEndOffset() const 36 | { 37 | integer_t endoffset = this->_vscrollbar->sliderPosition() + (this->visibleLines() * QHexMetrics::BYTES_PER_LINE); 38 | 39 | if(endoffset) 40 | endoffset--; 41 | 42 | return qMin(endoffset, this->_document->length()); 43 | } 44 | 45 | integer_t QHexMetrics::visibleLines() const 46 | { 47 | return currentContainer->height() / this->_charheight; 48 | } 49 | 50 | integer_t QHexMetrics::currentLine() const 51 | { 52 | QHexCursor* cursor = this->_document->cursor(); 53 | return this->_vscrollbar->sliderPosition() + (cursor->cursorY() / this->_charheight); 54 | } 55 | 56 | integer_t QHexMetrics::addressWidth() const 57 | { 58 | return this->_addresswidth; 59 | } 60 | 61 | integer_t QHexMetrics::charWidth() const 62 | { 63 | return this->_charwidth; 64 | } 65 | 66 | integer_t QHexMetrics::charHeight() const 67 | { 68 | return this->_charheight; 69 | } 70 | 71 | sinteger_t QHexMetrics::xPosAscii() const 72 | { 73 | return this->_xposascii; 74 | } 75 | 76 | sinteger_t QHexMetrics::xPosHex() const 77 | { 78 | return this->_xposhex; 79 | } 80 | 81 | sinteger_t QHexMetrics::xPosEnd() const 82 | { 83 | return this->_xposend; 84 | } 85 | 86 | void QHexMetrics::calculate(QHexDocument *document, const QFontMetrics &fm) 87 | { 88 | this->_document = document; 89 | this->calculate(fm); 90 | } 91 | 92 | void QHexMetrics::calculate(const QFontMetrics &fm) 93 | { 94 | this->calculateAddressWidth(); 95 | 96 | this->_charwidth = fm.width(" "); 97 | this->_charheight = fm.height(); 98 | 99 | this->_xposhex = this->_charwidth * (this->_addresswidth + 1); 100 | this->_xposascii = this->_xposhex + (this->_charwidth * (QHexMetrics::BYTES_PER_LINE * 3)); 101 | this->_xposend = this->_xposascii + (this->_charwidth * QHexMetrics::BYTES_PER_LINE); 102 | 103 | if(this->_document) 104 | { 105 | integer_t totlines = this->_document->length() / QHexMetrics::BYTES_PER_LINE; 106 | integer_t vislines = this->visibleLines(); 107 | 108 | if(totlines > vislines) 109 | { 110 | this->_vscrollbar->setRange(0, (totlines - vislines) + 1); 111 | this->_vscrollbar->setSingleStep(1); 112 | this->_vscrollbar->setPageStep(vislines); 113 | this->_vscrollbar->show(); 114 | } 115 | else 116 | this->_vscrollbar->hide(); 117 | 118 | currentContainer->setMinimumWidth(this->_xposend); 119 | } 120 | else 121 | { 122 | this->_vscrollbar->hide(); 123 | currentContainer->setMinimumWidth(0); 124 | } 125 | } 126 | 127 | bool QHexMetrics::ensureVisible() 128 | { 129 | if(!this->_document) 130 | return false; 131 | 132 | sinteger_t currline = this->currentLine(), vislines = this->visibleLines(); 133 | 134 | if(currline < this->_vscrollbar->sliderPosition() || currline > (this->_vscrollbar->sliderPosition() + vislines)) 135 | { 136 | this->_vscrollbar->setValue(qMax(currline - (vislines / 2), sinteger_t(0))); 137 | return true; 138 | } 139 | 140 | return false; 141 | } 142 | 143 | void QHexMetrics::calculateAddressWidth() 144 | { 145 | if(!this->_document) 146 | { 147 | this->_addresswidth = QHexMetrics::DEFAULT_ADDRESS_WIDTH; 148 | return; 149 | } 150 | 151 | QString addr = QString("%1").arg(this->_document->length() / QHexMetrics::BYTES_PER_LINE); 152 | 153 | if(this->_addresswidth >= addr.length()) 154 | return; 155 | 156 | this->_addresswidth = addr.length(); 157 | } 158 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/paint/qhexmetrics.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXMETRICS_H 2 | #define QHEXMETRICS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../document/qhexdocument.h" 8 | 9 | class QHexMetrics : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit QHexMetrics(QScrollBar* vscrollbar, QWidget *parent = 0); 15 | QHexDocument* document() const; 16 | QScrollBar* verticalScrollBar() const; 17 | QSize charSize() const; 18 | integer_t visibleStartOffset() const; 19 | integer_t visibleEndOffset() const; 20 | integer_t visibleLines() const; 21 | integer_t currentLine() const; 22 | integer_t addressWidth() const; 23 | integer_t charWidth() const; 24 | integer_t charHeight() const; 25 | sinteger_t xPosAscii() const; 26 | sinteger_t xPosHex() const; 27 | sinteger_t xPosEnd() const; 28 | void calculate(QHexDocument* document, const QFontMetrics& fm); 29 | void calculate(const QFontMetrics& fm); 30 | bool ensureVisible(); 31 | 32 | private: 33 | void calculateAddressWidth(); 34 | 35 | public: 36 | static const sinteger_t BYTES_PER_LINE; 37 | 38 | private: 39 | static const sinteger_t DEFAULT_ADDRESS_WIDTH; 40 | QScrollBar* _vscrollbar; 41 | QHexDocument* _document; 42 | sinteger_t _addresswidth; 43 | sinteger_t _charwidth, _charheight; 44 | sinteger_t _xposascii, _xposhex, _xposend; 45 | }; 46 | 47 | #endif // QHEXMETRICS_H 48 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/paint/qhexpainter.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexpainter.h" 2 | #include 3 | #include 4 | 5 | #define containerWidget static_cast(this->parent()) 6 | 7 | QString QHexPainter::UNPRINTABLE_CHAR; 8 | 9 | QHexPainter::QHexPainter(QHexMetrics *metrics, QWidget *parent) : QObject(parent), _metrics(metrics), _document(metrics->document()), _vscrollbar(metrics->verticalScrollBar()) 10 | { 11 | if(QHexPainter::UNPRINTABLE_CHAR.isEmpty()) 12 | QHexPainter::UNPRINTABLE_CHAR = "."; 13 | 14 | this->_boldfont = containerWidget->font(); 15 | this->_boldfont.setBold(true); 16 | } 17 | 18 | void QHexPainter::paint(QPaintEvent *e, QHexTheme *theme) 19 | { 20 | QPainter painter(containerWidget); 21 | 22 | this->drawLines(e, &painter, theme); 23 | this->drawBackground(&painter); 24 | this->drawCursor(&painter); 25 | } 26 | 27 | void QHexPainter::drawCursor(QPainter *painter) 28 | { 29 | if(!this->_document || !containerWidget->hasFocus()) 30 | return; 31 | 32 | QHexCursor* cursor = this->_document->cursor(); 33 | 34 | if(!cursor->blinking()) 35 | return; 36 | 37 | QHexMetrics* metrics = this->_metrics; 38 | 39 | if(cursor->isInsertMode()) 40 | painter->fillRect(cursor->cursorX(), cursor->cursorY(), 2, metrics->charHeight(), Qt::black); 41 | else 42 | painter->fillRect(cursor->cursorX(), cursor->cursorY() + metrics->charHeight() - 3, metrics->charWidth(), 2, Qt::black); 43 | } 44 | 45 | void QHexPainter::drawBackground(QPainter* painter) 46 | { 47 | integer_t span = this->_metrics->charWidth() / 2; 48 | 49 | painter->setBackgroundMode(Qt::TransparentMode); 50 | painter->setPen(containerWidget->palette().color(QPalette::WindowText)); 51 | painter->drawLine(this->_metrics->xPosHex() - span, 0, this->_metrics->xPosHex() - span, containerWidget->height()); 52 | painter->drawLine(this->_metrics->xPosAscii() - span, 0, this->_metrics->xPosAscii() - span, containerWidget->height()); 53 | painter->drawLine(this->_metrics->xPosEnd() + span, 0, this->_metrics->xPosEnd() + span, containerWidget->height()); 54 | } 55 | 56 | void QHexPainter::drawLines(QPaintEvent *e, QPainter* painter, QHexTheme *theme) 57 | { 58 | if(!this->_document) 59 | return; 60 | 61 | QRect r = e->rect(); 62 | integer_t slidepos = this->_vscrollbar->isVisible() ? this->_vscrollbar->sliderPosition() : 0; 63 | integer_t start = slidepos + (r.top() / this->_metrics->charHeight()); 64 | integer_t end = (slidepos + (r.bottom() / this->_metrics->charHeight())) + 1; // end + 1 removes the scroll bug 65 | 66 | for(integer_t i = start; i <= end; i++) 67 | { 68 | int y = (i - slidepos) * this->_metrics->charHeight(); 69 | this->drawLine(painter, theme, i, y); 70 | } 71 | } 72 | 73 | void QHexPainter::drawLine(QPainter *painter, QHexTheme* theme, integer_t line, integer_t y) 74 | { 75 | integer_t xhex = this->_metrics->xPosHex(), xascii = this->_metrics->xPosAscii(); 76 | integer_t linestart = line * QHexMetrics::BYTES_PER_LINE; 77 | 78 | painter->setBackgroundMode(Qt::TransparentMode); 79 | painter->setFont(containerWidget->font()); 80 | this->drawLineBackground(painter, theme, line, linestart, y); 81 | this->drawAddress(painter, theme, line, linestart, y); 82 | 83 | for(sinteger_t i = 0; i < QHexMetrics::BYTES_PER_LINE; i++) 84 | { 85 | integer_t offset = linestart + i; 86 | 87 | if(offset >= this->_document->length()) 88 | return; // Reached EOF 89 | 90 | uchar b = this->_document->at(offset); 91 | painter->setFont(containerWidget->font()); 92 | 93 | this->colorize(painter, offset, b); 94 | this->drawHex(painter, b, i, offset, xhex, y); 95 | this->drawAscii(painter, b, offset, xascii, y); 96 | } 97 | } 98 | 99 | void QHexPainter::drawLineBackground(QPainter *painter, QHexTheme *theme, integer_t line, integer_t linestart, integer_t y) 100 | { 101 | QHexCursor* cursor = this->_document->cursor(); 102 | QRect hexr(this->_metrics->xPosHex(), y, this->_metrics->xPosAscii() - (this->_metrics->charWidth() / 2), this->_metrics->charHeight()); 103 | QRect asciir(this->_metrics->xPosAscii(), y, (this->_metrics->charWidth() * QHexMetrics::BYTES_PER_LINE) + (this->_metrics->charWidth() / 2), this->_metrics->charHeight()); 104 | 105 | if((cursor->offset() >= linestart) && (cursor->offset() < (linestart + QHexMetrics::BYTES_PER_LINE))) // This is the Selected Line 106 | { 107 | painter->fillRect(hexr, theme->lineColor()); 108 | painter->fillRect(asciir, theme->lineColor()); 109 | } 110 | else if(line & 1) 111 | { 112 | painter->fillRect(hexr, theme->alternateLineColor()); 113 | painter->fillRect(asciir, theme->alternateLineColor()); 114 | } 115 | else 116 | { 117 | painter->fillRect(hexr, theme->baseColor()); 118 | painter->fillRect(asciir, theme->baseColor()); 119 | } 120 | } 121 | 122 | void QHexPainter::drawAddress(QPainter *painter, QHexTheme* theme, integer_t line, integer_t linestart, integer_t y) 123 | { 124 | QHexCursor* cursor = this->_document->cursor(); 125 | QFontMetrics fm = containerWidget->fontMetrics(); 126 | integer_t linemax = (this->_document->length() + QHexMetrics::BYTES_PER_LINE - 1) / QHexMetrics::BYTES_PER_LINE; 127 | painter->fillRect(0, y, this->_metrics->xPosHex() - (this->_metrics->charWidth() / 2), this->_metrics->charHeight(), theme->addressBackground()); 128 | 129 | if(!this->_document || (line >= linemax)) 130 | return; 131 | 132 | if((cursor->offset() >= linestart) && (cursor->offset() < (linestart + QHexMetrics::BYTES_PER_LINE))) // This is the Selected Line 133 | painter->setPen(theme->alternateAddressForeground()); 134 | else 135 | painter->setPen(theme->addressForeground()); 136 | 137 | QString addr = QString("%1").arg(this->_document->baseAddress() + (line * QHexMetrics::BYTES_PER_LINE), this->_metrics->addressWidth(), 16, QLatin1Char('0')).toUpper(); 138 | painter->drawText(0, y, fm.width(addr), this->_metrics->charHeight(), Qt::AlignLeft | Qt::AlignTop, addr); 139 | } 140 | 141 | void QHexPainter::drawHex(QPainter *painter, uchar b, sinteger_t i, integer_t offset, integer_t &x, integer_t y) 142 | { 143 | QString s = QString("%1").arg(b, 2, 16, QLatin1Char('0')).toUpper(); 144 | QFontMetrics fm = containerWidget->fontMetrics(); 145 | QRect r(x, y, fm.width(s), this->_metrics->charHeight()); 146 | 147 | this->mark(painter, r, offset, QHexCursor::HexPart); 148 | 149 | if(i < (QHexMetrics::BYTES_PER_LINE - 1)) 150 | r.setWidth(r.width() + this->_metrics->charWidth()); 151 | 152 | if(painter->backgroundMode() != Qt::TransparentMode) 153 | painter->fillRect(r, painter->background()); // NOTE: It's a bit ugly, but it works 154 | 155 | painter->drawText(r, Qt::AlignLeft | Qt::AlignTop, s); 156 | x += r.width(); 157 | } 158 | 159 | void QHexPainter::drawAscii(QPainter *painter, uchar b, integer_t offset, integer_t &x, integer_t y) 160 | { 161 | QFontMetrics fm = containerWidget->fontMetrics(); 162 | integer_t w; 163 | QString s; 164 | 165 | if(QChar(b).isPrint()) 166 | { 167 | w = fm.width(b); 168 | s = QString(b); 169 | } 170 | else 171 | { 172 | w = fm.width(QHexPainter::UNPRINTABLE_CHAR); 173 | s = QHexPainter::UNPRINTABLE_CHAR; 174 | } 175 | 176 | QRect r(x, y, w, this->_metrics->charHeight()); 177 | this->mark(painter, r, offset, QHexCursor::AsciiPart); 178 | 179 | painter->drawText(r, Qt::AlignLeft | Qt::AlignTop, s); 180 | x += w; 181 | } 182 | 183 | void QHexPainter::colorize(QPainter *painter, integer_t offset, uchar b) 184 | { 185 | QHexCursor* cursor = this->_document->cursor(); 186 | 187 | if(cursor->isSelected(offset)) 188 | { 189 | const QPalette& palette = containerWidget->palette(); 190 | painter->setBackgroundMode(Qt::OpaqueMode); 191 | painter->setBackground(palette.highlight()); 192 | painter->setPen(palette.highlightedText().color()); 193 | return; 194 | } 195 | 196 | // Prepare default palette 197 | painter->setBackgroundMode(Qt::TransparentMode); 198 | painter->setPen(Qt::black); 199 | 200 | if(this->applyMetadata(painter, offset)) 201 | return; 202 | 203 | if((b == 0x00) || (b == 0xFF)) 204 | painter->setPen(Qt::darkGray); 205 | } 206 | 207 | bool QHexPainter::applyMetadata(QPainter *painter, integer_t offset) 208 | { 209 | QHexMetadata* metadata = this->_document->metadata(); 210 | MetadataList metalist = metadata->fromOffset(offset); 211 | bool applied = false; 212 | 213 | foreach(QHexMetadataItem* metaitem, metalist) 214 | { 215 | if(!metaitem->contains(offset)) 216 | continue; 217 | 218 | applied = true; 219 | 220 | if(metaitem->hasBackColor()) 221 | { 222 | painter->setBackgroundMode(Qt::OpaqueMode); 223 | painter->setBackground(QBrush(metaitem->backColor())); 224 | } 225 | 226 | if(metaitem->hasForeColor()) 227 | painter->setPen(metaitem->foreColor()); 228 | 229 | if(metaitem->hasComment()) 230 | painter->setFont(this->_boldfont); 231 | } 232 | 233 | return applied; 234 | } 235 | 236 | bool QHexPainter::mark(QPainter *painter, const QRect &r, integer_t offset, QHexCursor::SelectedPart part) 237 | { 238 | QHexCursor* cursor = this->_document->cursor(); 239 | 240 | if((offset != cursor->offset()) || cursor->isAddressPartSelected() || (cursor->selectedPart() == part)) 241 | return false; 242 | 243 | painter->fillRect(r, Qt::darkGray); 244 | painter->setPen(Qt::white); 245 | return true; 246 | } 247 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/paint/qhexpainter.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXPAINTER_H 2 | #define QHEXPAINTER_H 3 | 4 | #include 5 | #include "../document/qhexdocument.h" 6 | #include "../document/qhextheme.h" 7 | #include "qhexmetrics.h" 8 | 9 | class QHexPainter : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit QHexPainter(QHexMetrics* metrics, QWidget *parent = 0); 15 | void paint(QPaintEvent* e, QHexTheme* theme); 16 | 17 | private: 18 | void drawCursor(QPainter *painter); 19 | void drawBackground(QPainter *painter); 20 | void drawLines(QPaintEvent* e, QPainter *painter, QHexTheme* theme); 21 | void drawLine(QPainter* painter, QHexTheme* theme, integer_t line, integer_t y); 22 | void drawLineBackground(QPainter *painter, QHexTheme* theme, integer_t line, integer_t linestart, integer_t y); 23 | void drawAddress(QPainter* painter, QHexTheme *theme, integer_t line, integer_t linestart, integer_t y); 24 | void drawHex(QPainter* painter, uchar b, sinteger_t i, integer_t offset, integer_t& x, integer_t y); 25 | void drawAscii(QPainter* painter, uchar b, integer_t offset, integer_t &x, integer_t y); 26 | void colorize(QPainter* painter, integer_t offset, uchar b); 27 | bool applyMetadata(QPainter* painter, integer_t offset); 28 | bool mark(QPainter* painter, const QRect& r, integer_t offset, QHexCursor::SelectedPart part); 29 | 30 | private: 31 | static QString UNPRINTABLE_CHAR; 32 | QHexMetrics* _metrics; 33 | QHexDocument* _document; 34 | QScrollBar* _vscrollbar; 35 | QFont _boldfont; 36 | }; 37 | 38 | #endif // QHEXPAINTER_H 39 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/qhexedit.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexedit.h" 2 | #include "qhexeditprivate.h" 3 | 4 | QHexEdit::QHexEdit(QWidget *parent): QFrame(parent) 5 | { 6 | this->_vscrollbar = new QScrollBar(Qt::Vertical); 7 | this->_scrollarea = new QScrollArea(); 8 | this->_hexedit_p = new QHexEditPrivate(this->_scrollarea, this->_vscrollbar); 9 | 10 | connect(this->_hexedit_p, &QHexEditPrivate::verticalScroll, this, &QHexEdit::verticalScroll); 11 | connect(this->_hexedit_p, &QHexEditPrivate::visibleLinesChanged, this, &QHexEdit::visibleLinesChanged); 12 | connect(this->_hexedit_p, &QHexEditPrivate::currentAddressChanged, this, &QHexEdit::currentAddressChanged); 13 | 14 | this->_scrollarea->setFocusPolicy(Qt::NoFocus); 15 | this->_scrollarea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Do not show vertical QScrollBar 16 | this->_scrollarea->setFrameStyle(QFrame::NoFrame); 17 | this->_scrollarea->setWidgetResizable(true); 18 | this->_scrollarea->setWidget(this->_hexedit_p); 19 | 20 | this->setFocusPolicy(Qt::NoFocus); 21 | this->setFocusProxy(this->_hexedit_p); 22 | 23 | this->_hlayout = new QHBoxLayout(); 24 | this->_hlayout->setSpacing(0); 25 | this->_hlayout->setMargin(0); 26 | this->_hlayout->addWidget(this->_scrollarea); 27 | this->_hlayout->addWidget(this->_vscrollbar); 28 | 29 | this->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 30 | this->setLayout(this->_hlayout); 31 | } 32 | 33 | QHexDocument *QHexEdit::document() const 34 | { 35 | return this->_hexedit_p->document(); 36 | } 37 | 38 | QHexMetrics *QHexEdit::metrics() const 39 | { 40 | return this->_hexedit_p->metrics(); 41 | } 42 | 43 | bool QHexEdit::readOnly() const 44 | { 45 | return this->_hexedit_p->readOnly(); 46 | } 47 | 48 | void QHexEdit::setReadOnly(bool b) 49 | { 50 | this->_hexedit_p->setReadOnly(b); 51 | } 52 | 53 | void QHexEdit::setDocument(QHexDocument *document) 54 | { 55 | this->_hexedit_p->setDocument(document); 56 | } 57 | 58 | void QHexEdit::scroll(QWheelEvent *event) 59 | { 60 | this->_hexedit_p->scroll(event); 61 | } 62 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/qhexedit.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXEDIT_H 2 | #define QHEXEDIT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "document/qhexdocument.h" 8 | #include "paint/qhexmetrics.h" 9 | 10 | class QHexEditPrivate; 11 | 12 | class QHexEdit : public QFrame 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit QHexEdit(QWidget *parent = 0); 18 | QHexDocument *document() const; 19 | QHexMetrics *metrics() const; 20 | bool readOnly() const; 21 | 22 | public slots: 23 | void setReadOnly(bool b); 24 | void setDocument(QHexDocument *document); 25 | void scroll(QWheelEvent *event); 26 | 27 | signals: 28 | void verticalScroll(integer_t value); 29 | void visibleLinesChanged(); 30 | /*! Contains the address, where the cursor is located. */ 31 | void currentAddressChanged(qint64 address); 32 | 33 | 34 | private: 35 | QHexEditPrivate* _hexedit_p; 36 | QScrollArea* _scrollarea; 37 | QScrollBar* _vscrollbar; 38 | QHBoxLayout* _hlayout; 39 | }; 40 | 41 | #endif // QHEXEDIT_H 42 | -------------------------------------------------------------------------------- /SQLiteExplorer/QHexEdit/qhexeditprivate.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXEDITPRIVATE_H 2 | #define QHEXEDITPRIVATE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "qhexedit.h" 8 | #include "document/qhexdocument.h" 9 | #include "document/qhextheme.h" 10 | #include "paint/qhexmetrics.h" 11 | 12 | class QHexEditPrivate : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit QHexEditPrivate(QScrollArea* scrollarea, QScrollBar* vscrollbar, QWidget *parent = 0); 18 | QHexDocument* document() const; 19 | QHexMetrics* metrics() const; 20 | bool readOnly() const; 21 | void setDocument(QHexDocument* document); 22 | void setReadOnly(bool b); 23 | void scroll(QWheelEvent *event); 24 | 25 | private: 26 | integer_t offsetFromPoint(const QPoint& pt, integer_t* bitindex = NULL) const; 27 | void toggleComment(const QPoint &pos); 28 | void updateCaret(integer_t offset, integer_t nibbleindex); 29 | void processDeleteEvents(); 30 | void processBackspaceEvents(); 31 | void processHexPart(int key); 32 | void processAsciiPart(int key); 33 | bool processMoveEvents(QKeyEvent* event); 34 | bool processSelectEvents(QKeyEvent* event); 35 | bool processTextInputEvents(QKeyEvent* event); 36 | bool processInsOvrEvents(QKeyEvent* event); 37 | bool processUndoRedo(QKeyEvent* event); 38 | bool processClipboardKeys(QKeyEvent* event); 39 | 40 | protected: 41 | void paintEvent(QPaintEvent* pe); 42 | void mousePressEvent(QMouseEvent* event); 43 | void mouseMoveEvent(QMouseEvent* event); 44 | void wheelEvent(QWheelEvent* event); 45 | void keyPressEvent(QKeyEvent* event); 46 | void resizeEvent(QResizeEvent*e); 47 | 48 | signals: 49 | void visibleLinesChanged(); 50 | void verticalScroll(int value); 51 | /*! Contains the address, where the cursor is located. */ 52 | void currentAddressChanged(qint64 address); 53 | 54 | 55 | private: 56 | static const integer_t WHELL_SCROLL_LINES; 57 | QScrollArea* _scrollarea; 58 | QScrollBar* _vscrollbar; 59 | QHexDocument* _document; 60 | QHexMetrics* _metrics; 61 | QHexTheme* _theme; 62 | bool _readonly; 63 | }; 64 | 65 | #endif // QHEXEDITPRIVATE_H 66 | -------------------------------------------------------------------------------- /SQLiteExplorer/QSQLiteMasterTreeView/QSQLiteMasterTreeView.cpp: -------------------------------------------------------------------------------- 1 | #include "QSQLiteMasterTreeView.h" 2 | 3 | QSQLiteMasterTreeView::QSQLiteMasterTreeView(QWidget *parent) 4 | : QTreeView(parent) 5 | { 6 | 7 | } 8 | 9 | void QSQLiteMasterTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) 10 | { 11 | Q_UNUSED(previous) 12 | emit signalCurrentChanged(current); 13 | } 14 | -------------------------------------------------------------------------------- /SQLiteExplorer/QSQLiteMasterTreeView/QSQLiteMasterTreeView.h: -------------------------------------------------------------------------------- 1 | #ifndef QSQLITETABLESTREEVIEW_H.h 2 | #define QSQLITETABLESTREEVIEW_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | class QSQLiteMasterTreeView : public QTreeView 9 | { 10 | Q_OBJECT 11 | 12 | enum ItemType{ 13 | ItemTypeDatabase = 0, 14 | ItemTypeFreeList, 15 | 16 | ItemTypeTable, 17 | ItemTypeIndex, 18 | ItemTypeTrigger, 19 | ItemTypeView, 20 | 21 | ItemTypeUnknown 22 | }; 23 | 24 | public: 25 | QSQLiteMasterTreeView(QWidget *parent = 0); 26 | 27 | // void InsertItem(QString dbPath, ItemType type, QString name, QString tableName); 28 | // void ClearItem(QString dbPath); 29 | // void EraseItem(QString dbPath, ItemType type, QString name); 30 | 31 | signals: 32 | 33 | // type,name,tableName分别是sqlite_master读出的type,name,tbl_name 34 | // type: table, index, trigger, view 35 | void signalItemClicked(QString dbPath, ItemType type, QString name, QString tableName); 36 | 37 | void signalCurrentChanged(const QModelIndex ¤t); 38 | 39 | protected: 40 | void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); 41 | 42 | }; 43 | 44 | #endif // QSQLITETABLESTREEVIEW_H 45 | -------------------------------------------------------------------------------- /SQLiteExplorer/QSQLiteMasterTreeView/QSQLiteMasterTreeView.pri: -------------------------------------------------------------------------------- 1 | HEADERS += \ 2 | $$PWD/QSQLiteMasterTreeView.h \ 3 | $$PWD/QSQLiteMasterTreeViewModel.h 4 | SOURCES += \ 5 | $$PWD/QSQLiteMasterTreeView.cpp \ 6 | $$PWD/QSQLiteMasterTreeViewModel.cpp 7 | 8 | INCLUDEPATH += $$PWD -------------------------------------------------------------------------------- /SQLiteExplorer/QSQLiteMasterTreeView/QSQLiteMasterTreeViewModel.cpp: -------------------------------------------------------------------------------- 1 | #include "QSQLiteMasterTreeViewModel.h" 2 | 3 | QSQLiteMasterTreeViewModel::QSQLiteMasterTreeViewModel(QObject *parent) 4 | : QAbstractItemModel(parent) 5 | { 6 | } 7 | 8 | QVariant QSQLiteMasterTreeViewModel::headerData(int section, Qt::Orientation orientation, int role) const 9 | { 10 | // FIXME: Implement me! 11 | } 12 | 13 | bool QSQLiteMasterTreeViewModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) 14 | { 15 | if (value != headerData(section, orientation, role)) { 16 | // FIXME: Implement me! 17 | emit headerDataChanged(orientation, section, section); 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | QModelIndex QSQLiteMasterTreeViewModel::index(int row, int column, const QModelIndex &parent) const 24 | { 25 | // FIXME: Implement me! 26 | } 27 | 28 | QModelIndex QSQLiteMasterTreeViewModel::parent(const QModelIndex &index) const 29 | { 30 | // FIXME: Implement me! 31 | } 32 | 33 | int QSQLiteMasterTreeViewModel::rowCount(const QModelIndex &parent) const 34 | { 35 | if (!parent.isValid()) 36 | return 0; 37 | 38 | // FIXME: Implement me! 39 | } 40 | 41 | int QSQLiteMasterTreeViewModel::columnCount(const QModelIndex &parent) const 42 | { 43 | if (!parent.isValid()) 44 | return 0; 45 | 46 | // FIXME: Implement me! 47 | } 48 | 49 | bool QSQLiteMasterTreeViewModel::hasChildren(const QModelIndex &parent) const 50 | { 51 | // FIXME: Implement me! 52 | } 53 | 54 | bool QSQLiteMasterTreeViewModel::canFetchMore(const QModelIndex &parent) const 55 | { 56 | // FIXME: Implement me! 57 | return false; 58 | } 59 | 60 | void QSQLiteMasterTreeViewModel::fetchMore(const QModelIndex &parent) 61 | { 62 | // FIXME: Implement me! 63 | } 64 | 65 | QVariant QSQLiteMasterTreeViewModel::data(const QModelIndex &index, int role) const 66 | { 67 | if (!index.isValid()) 68 | return QVariant(); 69 | 70 | // FIXME: Implement me! 71 | return QVariant(); 72 | } 73 | 74 | bool QSQLiteMasterTreeViewModel::setData(const QModelIndex &index, const QVariant &value, int role) 75 | { 76 | if (data(index, role) != value) { 77 | // FIXME: Implement me! 78 | emit dataChanged(index, index, QVector() << role); 79 | return true; 80 | } 81 | return false; 82 | } 83 | 84 | Qt::ItemFlags QSQLiteMasterTreeViewModel::flags(const QModelIndex &index) const 85 | { 86 | if (!index.isValid()) 87 | return Qt::NoItemFlags; 88 | 89 | return Qt::ItemIsEditable; // FIXME: Implement me! 90 | } 91 | 92 | bool QSQLiteMasterTreeViewModel::insertRows(int row, int count, const QModelIndex &parent) 93 | { 94 | beginInsertRows(parent, row, row + count - 1); 95 | // FIXME: Implement me! 96 | endInsertRows(); 97 | } 98 | 99 | bool QSQLiteMasterTreeViewModel::insertColumns(int column, int count, const QModelIndex &parent) 100 | { 101 | beginInsertColumns(parent, column, column + count - 1); 102 | // FIXME: Implement me! 103 | endInsertColumns(); 104 | } 105 | 106 | bool QSQLiteMasterTreeViewModel::removeRows(int row, int count, const QModelIndex &parent) 107 | { 108 | beginRemoveRows(parent, row, row + count - 1); 109 | // FIXME: Implement me! 110 | endRemoveRows(); 111 | } 112 | 113 | bool QSQLiteMasterTreeViewModel::removeColumns(int column, int count, const QModelIndex &parent) 114 | { 115 | beginRemoveColumns(parent, column, column + count - 1); 116 | // FIXME: Implement me! 117 | endRemoveColumns(); 118 | } 119 | -------------------------------------------------------------------------------- /SQLiteExplorer/QSQLiteMasterTreeView/QSQLiteMasterTreeViewModel.h: -------------------------------------------------------------------------------- 1 | #ifndef QSQLITETABLESTREEVIEWMODEL_H 2 | #define QSQLITETABLESTREEVIEWMODEL_H 3 | 4 | #include 5 | 6 | class QSQLiteMasterTreeViewModel : public QAbstractItemModel 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit QSQLiteMasterTreeViewModel(QObject *parent = 0); 12 | 13 | // Header: 14 | QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 15 | 16 | bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override; 17 | 18 | // Basic functionality: 19 | QModelIndex index(int row, int column, 20 | const QModelIndex &parent = QModelIndex()) const override; 21 | QModelIndex parent(const QModelIndex &index) const override; 22 | 23 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 24 | int columnCount(const QModelIndex &parent = QModelIndex()) const override; 25 | 26 | // Fetch data dynamically: 27 | bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; 28 | 29 | bool canFetchMore(const QModelIndex &parent) const override; 30 | void fetchMore(const QModelIndex &parent) override; 31 | 32 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 33 | 34 | // Editable: 35 | bool setData(const QModelIndex &index, const QVariant &value, 36 | int role = Qt::EditRole) override; 37 | 38 | Qt::ItemFlags flags(const QModelIndex& index) const override; 39 | 40 | // Add data: 41 | bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; 42 | bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; 43 | 44 | // Remove data: 45 | bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; 46 | bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; 47 | 48 | private: 49 | }; 50 | 51 | #endif // QSQLITETABLESTREEVIEWMODEL_H 52 | -------------------------------------------------------------------------------- /SQLiteExplorer/SQLWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "SQLWindow.h" 2 | #include "ui_sqlwindow.h" 3 | #include "mainwindow.h" 4 | #include "qsqlitetableview.h" 5 | #include "highlighter.h" 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | QSQLiteQueryWindow::QSQLiteQueryWindow(QWidget *parent) : 14 | QWidget(parent), 15 | ui(new Ui::QSQLiteQueryWindow) 16 | { 17 | ui->setupUi(this); 18 | 19 | m_pParent = qobject_cast(parent); 20 | m_pHighLighter = new Highlighter(); 21 | 22 | m_pTableView = new QSQLiteTableView(parent); 23 | connect(this, SIGNAL(signalSQLiteQuery(QString)), m_pTableView, SLOT(onSQLiteQueryReceived(QString))); 24 | connect(m_pTableView, SIGNAL(dataLoaded(QString)), this, SLOT(onDataLoaded(QString))); 25 | 26 | connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(onExecuteBtnClicked())); 27 | connect(ui->pushButton_2, SIGNAL(clicked(bool)), this, SLOT(onExplainBtnClicked())); 28 | 29 | // Init Splitter 30 | m_pSplitter = new QSplitter(Qt::Vertical); 31 | m_pSplitter->addWidget(ui->textEdit); 32 | m_pSplitter->addWidget(ui->widget); 33 | m_pSplitter->addWidget(m_pTableView); 34 | m_pSplitter->addWidget(ui->widget_2); 35 | 36 | m_pSplitter->setStretchFactor(0, 4); 37 | m_pSplitter->setStretchFactor(1, 1); 38 | m_pSplitter->setStretchFactor(2, 4); 39 | m_pSplitter->setStretchFactor(3, 1); 40 | 41 | ui->centralWidget->setLayout(new QVBoxLayout); 42 | ui->centralWidget->layout()->setMargin(0); 43 | ui->centralWidget->layout()->setSpacing(0); 44 | ui->centralWidget->layout()->addWidget(m_pSplitter); 45 | 46 | m_pHighLighter->setDocument(ui->textEdit->document()); 47 | 48 | QFont font; 49 | font.setFamily("Courier"); 50 | font.setFixedPitch(true); 51 | font.setPointSize(11); 52 | 53 | ui->textEdit->setFont(font); 54 | } 55 | 56 | QSQLiteQueryWindow::~QSQLiteQueryWindow() 57 | { 58 | delete ui; 59 | } 60 | 61 | void QSQLiteQueryWindow::onExecuteBtnClicked() 62 | { 63 | QTextCursor cursor = ui->textEdit->textCursor(); 64 | QString sql = cursor.selectedText(); 65 | if (sql.size() == 0) 66 | { 67 | sql = ui->textEdit->toPlainText(); 68 | } 69 | 70 | m_pTableView->SetDb(m_pParent->GetCurSQLite3DB()); 71 | emit signalSQLiteQuery(sql); 72 | } 73 | 74 | void QSQLiteQueryWindow::onExplainBtnClicked() 75 | { 76 | QTextCursor cursor = ui->textEdit->textCursor(); 77 | QString sql = cursor.selectedText(); 78 | if (sql.size() == 0) 79 | { 80 | sql = ui->textEdit->toPlainText(); 81 | } 82 | 83 | if (sql.size()) 84 | { 85 | sql = "EXPLAIN " + sql; 86 | } 87 | 88 | m_pTableView->SetDb(m_pParent->GetCurSQLite3DB()); 89 | emit signalSQLiteQuery(sql); 90 | } 91 | 92 | void QSQLiteQueryWindow::onDataLoaded(const QString &msg) 93 | { 94 | ui->label->setText(msg); 95 | } 96 | 97 | -------------------------------------------------------------------------------- /SQLiteExplorer/SQLWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef QSQLITEQUERYWINDOW_H 2 | #define QSQLITEQUERYWINDOW_H 3 | 4 | #include 5 | #include 6 | #include "highlighter.h" 7 | 8 | namespace Ui { 9 | class QSQLiteQueryWindow; 10 | } 11 | 12 | class QSQLiteTableView; 13 | class MainWindow; 14 | 15 | class QSQLiteQueryWindow : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit QSQLiteQueryWindow(QWidget *parent = 0); 21 | ~QSQLiteQueryWindow(); 22 | 23 | signals: 24 | void signalSQLiteQuery(const QString& sql); 25 | 26 | private slots: 27 | void onExecuteBtnClicked(); 28 | void onExplainBtnClicked(); 29 | void onDataLoaded(const QString& msg); 30 | private: 31 | Ui::QSQLiteQueryWindow *ui; 32 | 33 | QSQLiteTableView* m_pTableView; 34 | 35 | // QSplitter 36 | QSplitter* m_pSplitter; 37 | 38 | MainWindow* m_pParent; 39 | Highlighter* m_pHighLighter; 40 | }; 41 | 42 | #endif // QSQLITEQUERYWINDOW_H 43 | -------------------------------------------------------------------------------- /SQLiteExplorer/SQLWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | QSQLiteQueryWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 447 10 | 364 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 10 23 | 0 24 | 256 25 | 192 26 | 27 | 28 | 29 | 30 | 31 | 32 | 20 33 | 210 34 | 271 35 | 60 36 | 37 | 38 | 39 | 40 | 0 41 | 40 42 | 43 | 44 | 45 | 46 | 16777215 47 | 60 48 | 49 | 50 | 51 | 52 | 5 53 | 54 | 55 | 0 56 | 57 | 58 | 0 59 | 60 | 61 | 0 62 | 63 | 64 | 0 65 | 66 | 67 | 68 | 69 | Qt::Horizontal 70 | 71 | 72 | 73 | 40 74 | 20 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Execute 83 | 84 | 85 | 86 | 87 | 88 | 89 | Explain 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 | 20 112 | 280 113 | 261 114 | 41 115 | 116 | 117 | 118 | 119 | 0 120 | 121 | 122 | 0 123 | 124 | 125 | 0 126 | 127 | 128 | 0 129 | 130 | 131 | 0 132 | 133 | 134 | 135 | 136 | Status 137 | 138 | 139 | 140 | 141 | 142 | 143 | Qt::Horizontal 144 | 145 | 146 | 147 | 222 148 | 20 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /SQLiteExplorer/SQLite3DB.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | #include "sqlite3.h" 9 | #include "utils.h" 10 | #include "CppSQLite3.h" 11 | 12 | typedef deque cell_content; 13 | typedef deque table_content; 14 | 15 | struct TableSchema 16 | { 17 | string type; 18 | string name; 19 | string tbl_name; 20 | uint64_t rootpage; 21 | string sql; 22 | }; 23 | 24 | enum SQLite3DataType 25 | { 26 | SQLITE_TYPE_INTEGER = 1, 27 | SQLITE_TYPE_FLOAT = 2, 28 | SQLITE_TYPE_TEXT = 3, 29 | SQLITE_TYPE_BLOB = 4, 30 | SQLITE_TYPE_NULL = 5 31 | }; 32 | struct SQLite3Variant 33 | { 34 | public: 35 | SQLite3Variant():iVal(0), lfVal(0), valStartAddr(0), valLen(0), tVal(0), tStartAddr(0), tLen(0) 36 | {} 37 | int getInt(int nNullValue=0); 38 | sqlite_int64 getInt64(sqlite_int64 nNullValue=0); 39 | double getFloat(double fNullValue=0); 40 | const char* getString(const char* szNullValue=""); 41 | const unsigned char* getBlob(int& nLen); 42 | 43 | SQLite3DataType type; 44 | 45 | 46 | i64 iVal; 47 | double lfVal; 48 | string blob; 49 | string text; 50 | 51 | int valStartAddr; 52 | i64 valLen; 53 | 54 | // typeAndLen字段 55 | string tBlob; 56 | int tVal; 57 | int tStartAddr; 58 | i64 tLen; 59 | 60 | private: 61 | string desc; 62 | }; 63 | 64 | struct ContentArea 65 | { 66 | int m_startAddr; // 当前页的相对地址 67 | i64 m_len; // 长度 68 | 69 | public: 70 | void Clear() 71 | { 72 | m_startAddr = m_len = 0; 73 | } 74 | }; 75 | 76 | enum PageType 77 | { 78 | PAGE_TYPE_UNKNOWN = 0x00, 79 | PAGE_TYPE_INDEX_INTERIOR = 0x02, // B-Tree Interior 80 | PAGE_TYPE_TABLE_INTERIOR = 0x05, // B+Tree Interior 81 | PAGE_TYPE_INDEX_LEAF = 0x0A, // B-Tree Leaf 82 | PAGE_TYPE_TABLE_LEAF = 0x0D, // B+Tree Leaf 83 | PAGE_TYPE_OVERFLOW, // 溢出页 84 | PAGE_TYPE_FREELIST_TRUNK, // 自由页Trunk 85 | PAGE_TYPE_FREELIST_LEAF, // 自由页叶子页 86 | PAGE_TYPE_PTR_MAP, // auto_vacuum=incremental, page_2... 87 | }; 88 | 89 | struct PageUsageInfo 90 | { 91 | int pgno; // 当前页页号 92 | int parent; // 父页页号 93 | PageType type; // 当前页类型 94 | int ncell; // 当前页cell数量 95 | 96 | int overflow_page_idx; 97 | int overflow_cell_idx; 98 | string desc; 99 | 100 | PageUsageInfo() 101 | : pgno(0), parent(0), type(PAGE_TYPE_UNKNOWN), ncell(0) 102 | , overflow_page_idx(0), overflow_cell_idx(0) 103 | {} 104 | 105 | bool isRootPage(){ 106 | 107 | } 108 | }; 109 | 110 | 111 | class CSQLite3Page; 112 | class CSQLite3Payload; 113 | 114 | int decode_number(unsigned char *aData, /* Content being decoded */ 115 | int ofst, int nByte /* Start and size of decode */); 116 | 117 | /* 118 | ** Convert the var-int format into i64. Return the number of bytes 119 | ** in the var-int. Write the var-int value into *pVal. 120 | */ 121 | int decodeVarint(const unsigned char *z, int64_t *pVal); 122 | /* 123 | ** Extract a big-endian 32-bit integer 124 | */ 125 | unsigned int decodeInt32(const unsigned char *z); 126 | 127 | class CSQLite3DB : public CppSQLite3DB 128 | { 129 | friend class CSQLite3Page; 130 | friend class CSQLite3Payload; 131 | public: 132 | CSQLite3DB(const string& path); 133 | ~CSQLite3DB(void); 134 | 135 | // 获取所有表名称 136 | vector GetAllTableNames(); 137 | 138 | // 获取所有叶子页id 139 | vector > GetAllPageIdsAndType(const string &name); 140 | 141 | // 获取指定页原始内容 142 | string LoadPage(int pgno, bool decode = true); 143 | 144 | // 获取指定页的记录数量 145 | int GetCellCounts(int pgno); 146 | 147 | // 获取指定页,指定索引的cell原始数据 148 | string LoadCell(int pgno, int idx); 149 | 150 | // 解码指定页,指定索引的数据 151 | bool DecodeCell(int pgno, int idx, vector& var); 152 | 153 | // 获取页大小 154 | int GetPageSize(); 155 | 156 | // 获取指定表的列名称 157 | bool GetColumnNames(const string& tableName, vector& colNames); 158 | 159 | bool GetIndexNames(const string& name, const string& tableName, vector& colNames); 160 | 161 | // 执行sql查询,返回错误信息 162 | string ExecuteCmd(const string& sql, table_content& table, cell_content& headers); 163 | 164 | // 获取指定表的主键相关信息 165 | bool GetTablePrimaryKey(const string& tableName, vector& pkFieldName, vector& pkType, vector& pkIdx, bool& withoutRowid); 166 | 167 | // 获取表字段信息 168 | bool GetTableInfo(const string& tableName, table_content& tb); 169 | 170 | // 获取Page信息 171 | vector GetPageUsageInfos(bool freelist); 172 | 173 | // 获取数据库信息 174 | map GetDatabaseInfo(); 175 | 176 | // 设置数据库信息 177 | void SetDatabaseInfo(const string& key, const string& val); 178 | 179 | // 获取自由页信息 180 | vector GetFreeList(bool useCache = false); 181 | 182 | // 解析自由页 183 | void DecodeFreeListTrunkPage(int pgno, 184 | ContentArea& sNextTrunkPageNo, int& nNextTrunkPageNo, 185 | ContentArea& sLeafPageCounts, int& nLeafPageCounts, 186 | vector& sLeafPageNos, vector& nLeafPageNos, 187 | ContentArea& sUnused); 188 | 189 | private: 190 | bool OpenDatabase(); 191 | bool FileOpen(); 192 | void FileClose(); 193 | unsigned char* FileRead(int64_t ofst, int nByte); 194 | int64_t FileGetsize(void); 195 | 196 | void LoadSqliteMaster(); 197 | /* 198 | ** Describe the usages of a b-tree page 199 | */ 200 | void PageUsageBtree( 201 | int pgno, /* Page to describe */ 202 | int parent, /* Parent of this page. 0 for root pages */ 203 | int idx, /* Which child of the parent */ 204 | const char *zName /* Name of the table */ 205 | ); 206 | 207 | /* 208 | ** Find overflow pages of a cell and describe their usage. 209 | */ 210 | void PageUsageCell( 211 | unsigned char cType, /* Page type */ 212 | unsigned char *a, /* Cell content */ 213 | int pgno, /* page containing the cell */ 214 | int cellno /* Index of the cell on the page */ 215 | ); 216 | 217 | /* 218 | ** Compute the local payload size given the total payload size and 219 | ** the page size. 220 | */ 221 | i64 LocalPayload(i64 nPayload, char cType); 222 | 223 | private: 224 | string Pragma(const string& key); 225 | 226 | private: 227 | string m_path; 228 | int m_pagesize; /* Size of a database page */ 229 | uint64_t m_mxPage; /* Last page number */ 230 | int m_bRaw; /* True to access db file via OS APIs */ 231 | int m_dbfd; /* File descriptor for reading the DB */ 232 | sqlite3_file* m_pFd; /* File descriptor for non-raw mode */ 233 | 234 | map m_mapTableSchema; 235 | bool m_bTableInfoHasLoad; 236 | 237 | vector m_pageUsageInfo; 238 | map m_pragmaInfos; 239 | 240 | public: 241 | CSQLite3Page* m_pSqlite3Page; 242 | CSQLite3Payload* m_pSqlite3Payload; 243 | }; 244 | 245 | 246 | 247 | class CSQLite3Page 248 | { 249 | friend class CSQLite3Payload; 250 | public: 251 | CSQLite3Page(CSQLite3DB* parent); 252 | ~CSQLite3Page(); 253 | 254 | // 获取指定页的原始数据 255 | string LoadPage(int pgno, bool decode = true); 256 | 257 | // 获取指定页的类型 258 | int GetPageType(int pgno); 259 | 260 | // 获取指定页的记录数 261 | int GetCellCounts(int pgno); 262 | 263 | // 获取指定页的指定索引的原始cell 264 | string LoadCell(int pgno, int idx); 265 | 266 | // 解码指定页,指定索引的数据 267 | bool DecodeCell(int pgno, int idx, vector& var); 268 | 269 | private: 270 | void DecodePage(); 271 | 272 | /* 273 | ** Create a description for a single cell. 274 | ** 275 | ** The return value is the local cell size. 276 | */ 277 | i64 GetPayloadSize(unsigned char cType, unsigned char* a); 278 | 279 | /* 280 | ** Compute the local payload size given the total payload size and 281 | ** the page size. 282 | */ 283 | i64 LocalPayload(i64 nPayload, char cType); 284 | 285 | void Clear(); 286 | 287 | public: 288 | CSQLite3DB* m_pParent; 289 | 290 | string m_pageRawContent; 291 | int m_pgno; 292 | 293 | uint8_t m_cType; 294 | uint16_t m_firstFreeBlockAddr; 295 | uint16_t m_cellCounts; 296 | uint16_t m_startOfCellContentAddr; 297 | uint8_t m_fragmentBytes; 298 | int m_rightChildPageNumber; 299 | 300 | 301 | ContentArea m_pageHeaderArea; // 页头区域 302 | ContentArea m_cellIndexArea; // cellIndex区域 303 | vector m_payloadArea; // payload区域 304 | ContentArea m_unusedArea; // 未使用区域 305 | vector m_freeSpaceArea;// 空闲链表区域 306 | }; 307 | 308 | 309 | class CSQLite3Payload 310 | { 311 | friend class CSQLite3DB; 312 | friend class CSQLite3Page; 313 | public: 314 | CSQLite3Payload(CSQLite3Page* parent); 315 | ~CSQLite3Payload(); 316 | 317 | 318 | /* 319 | ** Create a description for a single cell. 320 | ** 321 | ** The return value is the local cell size. 322 | */ 323 | void DescribeCell( 324 | unsigned char cType, /* Page type */ 325 | unsigned char *a /* Cell content */ 326 | ); 327 | 328 | /* 329 | ** Describe cell content. 330 | */ 331 | bool DescribeContent(); 332 | 333 | int GetLeftChild(){return m_leftChild;} 334 | i64 GetRowid(){return m_rowid;} 335 | 336 | 337 | CSQLite3Page* m_pParent; 338 | string m_cellContent; 339 | string m_payloadContent; 340 | 341 | // 下面所有StartAddr都是相对于m_rawContent起点来说的。 342 | i64 m_nPayload; // 整个cell大小 Not Contain itself 343 | int m_nPayloadStartAddr; 344 | i64 m_nPayloadLen; 345 | i64 m_nLocal; // cell在当前page大小 346 | 347 | unsigned char m_cType; 348 | 349 | // 350 | int m_leftChild; 351 | int m_leftChildStartAddr; 352 | i64 m_leftChildLen; // 左孩子varint长度 353 | i64 m_rowid; 354 | int m_rowidStartAddr; 355 | i64 m_rowidLen; // rowid varint len 356 | string m_pk; 357 | i64 m_cellHeaderSize; // Contain itself 358 | int m_cellHeaderSizeStartAddr; 359 | i64 m_cellHeaderSizeLen; 360 | vector m_datas; 361 | }; 362 | -------------------------------------------------------------------------------- /SQLiteExplorer/SQLiteExplorer.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-09-09T15:46:50 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | RC_ICONS = ui/app.ico 9 | 10 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 11 | 12 | TARGET = SQLiteExplorer 13 | TEMPLATE = app 14 | 15 | # The following define makes your compiler emit warnings if you use 16 | # any feature of Qt which as been marked as deprecated (the exact warnings 17 | # depend on your compiler). Please consult the documentation of the 18 | # deprecated API in order to know how to port your code away from it. 19 | DEFINES += QT_DEPRECATED_WARNINGS 20 | 21 | # You can also make your code fail to compile if you use deprecated APIs. 22 | # In order to do so, uncomment the following line. 23 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 24 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 25 | 26 | INCLUDEPATH += ../sqlite3 27 | 28 | 29 | SOURCES += \ 30 | main.cpp \ 31 | mainwindow.cpp \ 32 | SQLite3DB.cpp \ 33 | utils.cpp \ 34 | qsqlitetableview.cpp \ 35 | pixitem.cpp \ 36 | CppSQLite3.cpp \ 37 | DataWindow.cpp \ 38 | GraphWindow.cpp \ 39 | SQLWindow.cpp \ 40 | DialogAbout.cpp \ 41 | HexWindow.cpp \ 42 | highlighter.cpp 43 | 44 | HEADERS += \ 45 | mainwindow.h \ 46 | SQLite3DB.h \ 47 | utils.h \ 48 | qsqlitetableview.h \ 49 | pixitem.h \ 50 | CppSQLite3.h \ 51 | DataWindow.h \ 52 | GraphWindow.h \ 53 | SQLWindow.h \ 54 | DialogAbout.h \ 55 | HexWindow.h \ 56 | highlighter.h 57 | 58 | CONFIG += c++11 59 | 60 | FORMS += \ 61 | mainwindow.ui \ 62 | DataWindow.ui \ 63 | GraphWindow.ui \ 64 | SQLWindow.ui \ 65 | DialogAbout.ui \ 66 | HexWindow.ui 67 | 68 | DESTDIR = $$PWD/../bin 69 | 70 | LIBS = -L$$DESTDIR -lsqlite3 71 | 72 | include(QHexEdit/QHexEdit.pri) 73 | include(QSQLiteMasterTreeView/QSQLiteMasterTreeView.pri) 74 | include(elasticnodes/elasticnodes.pri) 75 | 76 | RESOURCES += \ 77 | ui_icon.qrc 78 | 79 | DISTFILES += 80 | -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/edge.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #include "edge.h" 52 | #include "node.h" 53 | 54 | #include 55 | 56 | #include 57 | 58 | static const double Pi = 3.14159265358979323846264338327950288419717; 59 | static double TwoPi = 2.0 * Pi; 60 | 61 | //! [0] 62 | Edge::Edge(Node *sourceNode, Node *destNode) 63 | : arrowSize(10) 64 | { 65 | setAcceptedMouseButtons(0); 66 | source = sourceNode; 67 | dest = destNode; 68 | source->addEdge(this); 69 | dest->addEdge(this); 70 | adjust(); 71 | } 72 | //! [0] 73 | 74 | //! [1] 75 | Node *Edge::sourceNode() const 76 | { 77 | return source; 78 | } 79 | 80 | Node *Edge::destNode() const 81 | { 82 | return dest; 83 | } 84 | //! [1] 85 | 86 | //! [2] 87 | void Edge::adjust() 88 | { 89 | if (!source || !dest) 90 | return; 91 | 92 | QLineF line(mapFromItem(source, 0, 0), mapFromItem(dest, 0, 0)); 93 | qreal length = line.length(); 94 | 95 | prepareGeometryChange(); 96 | 97 | if (length > qreal(20.)) { 98 | QPointF edgeOffset((line.dx() * 10) / length, (line.dy() * 10) / length); 99 | sourcePoint = line.p1() + edgeOffset; 100 | destPoint = line.p2() - edgeOffset; 101 | } else { 102 | sourcePoint = destPoint = line.p1(); 103 | } 104 | } 105 | //! [2] 106 | 107 | //! [3] 108 | QRectF Edge::boundingRect() const 109 | { 110 | if (!source || !dest) 111 | return QRectF(); 112 | 113 | qreal penWidth = 1; 114 | qreal extra = (penWidth + arrowSize) / 2.0; 115 | 116 | return QRectF(sourcePoint, QSizeF(destPoint.x() - sourcePoint.x(), 117 | destPoint.y() - sourcePoint.y())) 118 | .normalized() 119 | .adjusted(-extra, -extra, extra, extra); 120 | } 121 | //! [3] 122 | 123 | //! [4] 124 | void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) 125 | { 126 | if (!source || !dest) 127 | return; 128 | 129 | QLineF line(sourcePoint, destPoint); 130 | if (qFuzzyCompare(line.length(), qreal(0.))) 131 | return; 132 | //! [4] 133 | 134 | //! [5] 135 | // Draw the line itself 136 | painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); 137 | painter->drawLine(line); 138 | //! [5] 139 | 140 | //! [6] 141 | // Draw the arrows 142 | double angle = ::acos(line.dx() / line.length()); 143 | if (line.dy() >= 0) 144 | angle = TwoPi - angle; 145 | 146 | // QPointF sourceArrowP1 = sourcePoint + QPointF(sin(angle + Pi / 3) * arrowSize, 147 | // cos(angle + Pi / 3) * arrowSize); 148 | // QPointF sourceArrowP2 = sourcePoint + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, 149 | // cos(angle + Pi - Pi / 3) * arrowSize); 150 | QPointF destArrowP1 = destPoint + QPointF(sin(angle - Pi / 3) * arrowSize, 151 | cos(angle - Pi / 3) * arrowSize); 152 | QPointF destArrowP2 = destPoint + QPointF(sin(angle - Pi + Pi / 3) * arrowSize, 153 | cos(angle - Pi + Pi / 3) * arrowSize); 154 | 155 | painter->setBrush(Qt::black); 156 | //painter->drawPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2); 157 | painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); 158 | } 159 | //! [6] 160 | -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/edge.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #ifndef EDGE_H 52 | #define EDGE_H 53 | 54 | #include 55 | 56 | class Node; 57 | 58 | //! [0] 59 | class Edge : public QGraphicsItem 60 | { 61 | public: 62 | Edge(Node *sourceNode, Node *destNode); 63 | 64 | Node *sourceNode() const; 65 | Node *destNode() const; 66 | 67 | void adjust(); 68 | 69 | enum { Type = UserType + 2 }; 70 | int type() const Q_DECL_OVERRIDE { return Type; } 71 | 72 | protected: 73 | QRectF boundingRect() const Q_DECL_OVERRIDE; 74 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE; 75 | 76 | private: 77 | Node *source, *dest; 78 | 79 | QPointF sourcePoint; 80 | QPointF destPoint; 81 | qreal arrowSize; 82 | }; 83 | //! [0] 84 | 85 | #endif // EDGE_H 86 | -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/elasticnodes.pri: -------------------------------------------------------------------------------- 1 | HEADERS += \ 2 | $$PWD/edge.h \ 3 | $$PWD/node.h \ 4 | $$PWD/graphwidget.h 5 | SOURCES += \ 6 | $$PWD/edge.cpp \ 7 | $$PWD/node.cpp \ 8 | $$PWD/graphwidget.cpp 9 | 10 | INCLUDEPATH += $$PWD -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/graphwidget.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #ifndef GRAPHWIDGET_H 52 | #define GRAPHWIDGET_H 53 | 54 | #include 55 | 56 | class Node; 57 | 58 | //! [0] 59 | class GraphWidget : public QGraphicsView 60 | { 61 | Q_OBJECT 62 | 63 | public: 64 | GraphWidget(QWidget *parent = 0); 65 | 66 | void SetPath(QString path); 67 | void itemMoved(); 68 | 69 | void clear(); 70 | 71 | public slots: 72 | void shuffle(); 73 | void zoomIn(); 74 | void zoomOut(); 75 | void StartAnimate(bool start); 76 | 77 | protected: 78 | void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; 79 | void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; 80 | #ifndef QT_NO_WHEELEVENT 81 | void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; 82 | #endif 83 | void drawBackground(QPainter *painter, const QRectF &rect) Q_DECL_OVERRIDE; 84 | 85 | void scaleView(qreal scaleFactor); 86 | 87 | private: 88 | int timerId; 89 | Node *centerNode; 90 | bool m_start; 91 | }; 92 | //! [0] 93 | 94 | #endif // GRAPHWIDGET_H 95 | -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/main.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #include "graphwidget.h" 52 | 53 | #include 54 | #include 55 | #include 56 | 57 | int main(int argc, char **argv) 58 | { 59 | QApplication app(argc, argv); 60 | qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); 61 | 62 | GraphWidget *widget = new GraphWidget; 63 | 64 | QMainWindow mainWindow; 65 | mainWindow.setCentralWidget(widget); 66 | 67 | mainWindow.show(); 68 | return app.exec(); 69 | } 70 | -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/node.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #include "edge.h" 52 | #include "node.h" 53 | #include "graphwidget.h" 54 | 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | //! [0] 61 | Node::Node(GraphWidget *graphWidget, NodeProp np) 62 | : graph(graphWidget) 63 | , m_np(np) 64 | { 65 | setFlag(ItemIsMovable); 66 | setFlag(ItemSendsGeometryChanges); 67 | setCacheMode(DeviceCoordinateCache); 68 | setZValue(-1); 69 | 70 | 71 | m_np.rc.setWidth(20/np.rc.height()*np.rc.width()*3); 72 | m_np.rc.setHeight(20); 73 | } 74 | //! [0] 75 | 76 | //! [1] 77 | void Node::addEdge(Edge *edge) 78 | { 79 | edgeList << edge; 80 | edge->adjust(); 81 | } 82 | 83 | QList Node::edges() const 84 | { 85 | return edgeList; 86 | } 87 | //! [1] 88 | 89 | //! [2] 90 | void Node::calculateForces() 91 | { 92 | if (!scene() || scene()->mouseGrabberItem() == this) { 93 | newPos = pos(); 94 | return; 95 | } 96 | //! [2] 97 | 98 | //! [3] 99 | // Sum up all forces pushing this item away 100 | qreal xvel = 0; 101 | qreal yvel = 0; 102 | foreach (QGraphicsItem *item, scene()->items()) { 103 | Node *node = qgraphicsitem_cast(item); 104 | if (!node) 105 | continue; 106 | 107 | QPointF vec = mapToItem(node, 0, 0); 108 | qreal dx = vec.x(); 109 | qreal dy = vec.y(); 110 | double l = 2.0 * (dx * dx + dy * dy); 111 | if (l > 0) { 112 | xvel += (dx * 150.0) / l; 113 | yvel += (dy * 150.0) / l; 114 | } 115 | } 116 | //! [3] 117 | 118 | //! [4] 119 | // Now subtract all forces pulling items together 120 | double weight = (edgeList.size() + 1) * 10; 121 | foreach (Edge *edge, edgeList) { 122 | QPointF vec; 123 | if (edge->sourceNode() == this) 124 | vec = mapToItem(edge->destNode(), 0, 0); 125 | else 126 | vec = mapToItem(edge->sourceNode(), 0, 0); 127 | xvel -= vec.x() / weight; 128 | yvel -= vec.y() / weight; 129 | } 130 | //! [4] 131 | 132 | //! [5] 133 | if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) 134 | xvel = yvel = 0; 135 | //! [5] 136 | 137 | //! [6] 138 | QRectF sceneRect = scene()->sceneRect(); 139 | newPos = pos() + QPointF(xvel, yvel); 140 | newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); 141 | newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); 142 | } 143 | //! [6] 144 | 145 | //! [7] 146 | bool Node::advance() 147 | { 148 | if (newPos == pos()) 149 | return false; 150 | 151 | setPos(newPos); 152 | return true; 153 | } 154 | //! [7] 155 | 156 | //! [8] 157 | QRectF Node::boundingRect() const 158 | { 159 | qreal adjust = 2; 160 | return QRectF(0-m_np.rc.width()/2-adjust, 161 | 0-m_np.rc.height()/2-adjust, 162 | m_np.rc.width()+3+adjust, 163 | m_np.rc.height()+3+adjust); 164 | //return QRectF(- adjust, - adjust, m_width + adjust, m_height + adjust); 165 | } 166 | //! [8] 167 | 168 | //! [9] 169 | QPainterPath Node::shape() const 170 | { 171 | QPainterPath path; 172 | //path.addEllipse(-10, -10, 50, 20); 173 | path.addEllipse(0-m_np.rc.width()/2, 0-m_np.rc.height()/2, m_np.rc.width(), m_np.rc.height()); 174 | return path; 175 | } 176 | //! [9] 177 | 178 | //! [10] 179 | void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) 180 | { 181 | painter->setPen(Qt::NoPen); 182 | painter->setBrush(Qt::darkGray); 183 | //painter->drawEllipse(-7, -7, 20, 20); 184 | painter->drawRoundedRect(0-m_np.rc.width()/2+3, 0-m_np.rc.height()/2+3, m_np.rc.width(), m_np.rc.height(), 2, 2); 185 | 186 | //QRadialGradient gradient(-3, -3, 10); 187 | QLinearGradient gradient(-3, -3, m_np.rc.width(), m_np.rc.height()); 188 | 189 | gradient.setColorAt(0, QColor(m_np.fillcolor)); 190 | // if (option->state & QStyle::State_Sunken) { 191 | // //gradient.setCenter(3, 3); 192 | // //gradient.setFocalPoint(3, 3); 193 | // gradient.setColorAt(1, QColor(Qt::yellow).light(120)); 194 | // gradient.setColorAt(0, QColor(Qt::darkYellow).light(120)); 195 | // } else { 196 | // gradient.setColorAt(0, Qt::yellow); 197 | // gradient.setColorAt(1, Qt::darkYellow); 198 | // } 199 | 200 | painter->setBrush(gradient); 201 | 202 | painter->setPen(QPen(Qt::black, 0)); 203 | //painter->drawEllipse(-10, -10, 20, 20); 204 | //painter->drawRoundedRect(-10, -10, 50, 20, 2, 2); 205 | painter->drawRoundedRect(0-m_np.rc.width()/2, 0-m_np.rc.height()/2, m_np.rc.width(), m_np.rc.height(), 2, 2); 206 | 207 | QRectF rc(0-m_np.rc.width()/2+3, 0-m_np.rc.height()/2, m_np.rc.width(), m_np.rc.height()); 208 | 209 | QFont font; 210 | font.setPointSize(14); 211 | painter->setFont(font); 212 | painter->drawText(rc, m_np.label); 213 | } 214 | //! [10] 215 | 216 | //! [11] 217 | QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) 218 | { 219 | switch (change) { 220 | case ItemPositionHasChanged: 221 | foreach (Edge *edge, edgeList) 222 | edge->adjust(); 223 | graph->itemMoved(); 224 | break; 225 | default: 226 | break; 227 | }; 228 | 229 | return QGraphicsItem::itemChange(change, value); 230 | } 231 | //! [11] 232 | 233 | //! [12] 234 | void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) 235 | { 236 | update(); 237 | QGraphicsItem::mousePressEvent(event); 238 | } 239 | 240 | void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 241 | { 242 | update(); 243 | QGraphicsItem::mouseReleaseEvent(event); 244 | } 245 | //! [12] 246 | -------------------------------------------------------------------------------- /SQLiteExplorer/elasticnodes/node.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #ifndef NODE_H 52 | #define NODE_H 53 | 54 | #include 55 | #include 56 | 57 | struct NodeProp 58 | { 59 | NodeProp(){} 60 | QString name; 61 | QRectF rc; 62 | QString label; 63 | QString style; 64 | QString shape; 65 | QString color; 66 | QString fillcolor; 67 | }; 68 | 69 | class Edge; 70 | class GraphWidget; 71 | QT_BEGIN_NAMESPACE 72 | class QGraphicsSceneMouseEvent; 73 | QT_END_NAMESPACE 74 | 75 | //! [0] 76 | class Node : public QGraphicsItem 77 | { 78 | public: 79 | Node(GraphWidget *graphWidget, NodeProp np); 80 | 81 | void addEdge(Edge *edge); 82 | QList edges() const; 83 | 84 | enum { Type = UserType + 1 }; 85 | int type() const Q_DECL_OVERRIDE { return Type; } 86 | 87 | void calculateForces(); 88 | bool advance(); 89 | 90 | QRectF boundingRect() const Q_DECL_OVERRIDE; 91 | QPainterPath shape() const Q_DECL_OVERRIDE; 92 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE; 93 | 94 | protected: 95 | QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE; 96 | 97 | void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 98 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; 99 | 100 | private: 101 | QList edgeList; 102 | QPointF newPos; 103 | GraphWidget *graph; 104 | NodeProp m_np; 105 | }; 106 | //! [0] 107 | 108 | #endif // NODE_H 109 | -------------------------------------------------------------------------------- /SQLiteExplorer/graphviz-2.38.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/graphviz-2.38.zip -------------------------------------------------------------------------------- /SQLiteExplorer/highlighter.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #include "highlighter.h" 52 | 53 | //! [0] 54 | Highlighter::Highlighter(QTextDocument *parent) 55 | : QSyntaxHighlighter(parent) 56 | { 57 | HighlightingRule rule; 58 | 59 | keywordFormat.setForeground(Qt::darkBlue); 60 | keywordFormat.setFontWeight(QFont::Bold); 61 | QStringList keywordPatterns; 62 | // keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b" 63 | // << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b" 64 | // << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b" 65 | // << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b" 66 | // << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b" 67 | // << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b" 68 | // << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b" 69 | // << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b" 70 | // << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b" 71 | // << "\\bvoid\\b" << "\\bvolatile\\b"; 72 | 73 | keywordPatterns << "ABORT" << "CREATE" << "FROM" << "NATURAL" 74 | << "ACTION" << "CROSS" << "FULL" << "NO" 75 | << "ADD" << "CURRENT_DATE" << "GLOB" << "NOT" 76 | << "AFTER" << "CURRENT_TIME" << "GROUP" << "NOTNULL" 77 | << "ALL" << "CURRENT_TIMESTAMP" << "HAVING" << "NULL" 78 | << "ALTER" << "DATABASE" << "IF" << "OF" 79 | << "ANALYZE" << "DEFAULT" << "IGNORE" << "OFFSET" 80 | << "AND" << "DEFERRABLE" << "IMMEDIATE" << "ON" 81 | << "AS" << "DEFERRED" << "IN" << "OR" 82 | << "ASC" << "DELETE" << "INDEX" << "ORDER" 83 | << "ATTACH" << "DESC" << "INDEXED" << "OUTER" 84 | << "AUTOINCREMENT" << "DETACH" << "INITIALLY" << "PLAN" 85 | << "BEFORE" << "DISTINCT" << "INNER" << "PRAGMA" 86 | << "BEGIN" << "DROP" << "INSERT" << "PRIMARY" 87 | << "BETWEEN" << "EACH" << "INSTEAD" << "QUERY" 88 | << "BY" << "ELSE" << "INTERSECT" << "RAISE" 89 | << "CASCADE" << "END" << "INTO" << "RECURSIVE" 90 | << "CASE" << "ESCAPE" << "IS" << "REFERENCES" 91 | << "CAST" << "EXCEPT" << "ISNULL" << "REGEXP" 92 | << "CHECK" << "EXCLUSIVE" << "JOIN" << "REINDEX" 93 | << "COLLATE" << "EXISTS" << "KEY" << "RELEASE" 94 | << "COLUMN" << "EXPLAIN" << "LEFT" << "RENAME" 95 | << "COMMIT" << "FAIL" << "LIKE" << "REPLACE" 96 | << "CONFLICT" << "FOR" << "LIMIT" << "RESTRICT" 97 | << "CONSTRAINT" << "FOREIGN" << "MATCH" << "RIGHT" 98 | << "SELECT" << "WHERE" << "UNIQUE" << "TRANSACTION"; 99 | 100 | foreach (const QString &pattern, keywordPatterns) { 101 | QString pattern2 = "\\b" + pattern + "\\b"; 102 | QRegExp rx(pattern2); 103 | rx.setCaseSensitivity(Qt::CaseInsensitive); 104 | rule.pattern = rx; 105 | rule.format = keywordFormat; 106 | highlightingRules.append(rule); 107 | //! [0] //! [1] 108 | } 109 | //! [1] 110 | 111 | //! [2] 112 | // classFormat.setFontWeight(QFont::Bold); 113 | // classFormat.setForeground(Qt::darkMagenta); 114 | // rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b"); 115 | // rule.format = classFormat; 116 | // highlightingRules.append(rule); 117 | //! [2] 118 | 119 | //! [3] 120 | singleLineCommentFormat.setForeground(Qt::red); 121 | rule.pattern = QRegExp("--[^\n]*"); 122 | rule.format = singleLineCommentFormat; 123 | highlightingRules.append(rule); 124 | 125 | //multiLineCommentFormat.setForeground(Qt::red); 126 | //! [3] 127 | 128 | //! [4] 129 | // quotationFormat.setForeground(Qt::darkGreen); 130 | // rule.pattern = QRegExp("\".*\""); 131 | // rule.format = quotationFormat; 132 | // highlightingRules.append(rule); 133 | //! [4] 134 | 135 | //! [5] 136 | // functionFormat.setFontItalic(true); 137 | // functionFormat.setForeground(Qt::blue); 138 | // rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()"); 139 | // rule.format = functionFormat; 140 | // highlightingRules.append(rule); 141 | //! [5] 142 | 143 | //! [6] 144 | // commentStartExpression = QRegExp("/\\*"); 145 | // commentEndExpression = QRegExp("\\*/"); 146 | } 147 | //! [6] 148 | 149 | //! [7] 150 | void Highlighter::highlightBlock(const QString &text) 151 | { 152 | foreach (const HighlightingRule &rule, highlightingRules) { 153 | QRegExp expression(rule.pattern); 154 | int index = expression.indexIn(text); 155 | while (index >= 0) { 156 | int length = expression.matchedLength(); 157 | setFormat(index, length, rule.format); 158 | index = expression.indexIn(text, index + length); 159 | } 160 | } 161 | //! [7] //! [8] 162 | setCurrentBlockState(0); 163 | //! [8] 164 | 165 | ////! [9] 166 | // int startIndex = 0; 167 | // if (previousBlockState() != 1) 168 | // startIndex = commentStartExpression.indexIn(text); 169 | 170 | ////! [9] //! [10] 171 | // while (startIndex >= 0) { 172 | ////! [10] //! [11] 173 | // int endIndex = commentEndExpression.indexIn(text, startIndex); 174 | // int commentLength; 175 | // if (endIndex == -1) { 176 | // setCurrentBlockState(1); 177 | // commentLength = text.length() - startIndex; 178 | // } else { 179 | // commentLength = endIndex - startIndex 180 | // + commentEndExpression.matchedLength(); 181 | // } 182 | // setFormat(startIndex, commentLength, multiLineCommentFormat); 183 | // startIndex = commentStartExpression.indexIn(text, startIndex + commentLength); 184 | // } 185 | } 186 | //! [11] 187 | -------------------------------------------------------------------------------- /SQLiteExplorer/highlighter.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #ifndef HIGHLIGHTER_H 52 | #define HIGHLIGHTER_H 53 | 54 | #include 55 | #include 56 | 57 | QT_BEGIN_NAMESPACE 58 | class QTextDocument; 59 | QT_END_NAMESPACE 60 | 61 | //! [0] 62 | class Highlighter : public QSyntaxHighlighter 63 | { 64 | Q_OBJECT 65 | 66 | public: 67 | Highlighter(QTextDocument *parent = 0); 68 | 69 | protected: 70 | void highlightBlock(const QString &text) Q_DECL_OVERRIDE; 71 | 72 | private: 73 | struct HighlightingRule 74 | { 75 | QRegExp pattern; 76 | QTextCharFormat format; 77 | }; 78 | QVector highlightingRules; 79 | 80 | QRegExp commentStartExpression; 81 | QRegExp commentEndExpression; 82 | 83 | QTextCharFormat keywordFormat; 84 | //QTextCharFormat classFormat; 85 | QTextCharFormat singleLineCommentFormat; 86 | //QTextCharFormat multiLineCommentFormat; 87 | //QTextCharFormat quotationFormat; 88 | //QTextCharFormat functionFormat; 89 | }; 90 | //! [0] 91 | 92 | #endif // HIGHLIGHTER_H 93 | -------------------------------------------------------------------------------- /SQLiteExplorer/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.resize(1600, 800); 9 | w.show(); 10 | 11 | return a.exec(); 12 | } 13 | -------------------------------------------------------------------------------- /SQLiteExplorer/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "pixitem.h" 24 | #include 25 | #include 26 | 27 | #include "HexWindow.h" 28 | #include "QSQLiteMasterTreeView.h" 29 | #include "SQLite3DB.h" 30 | 31 | #include "GraphWindow.h" 32 | #include "DataWindow.h" 33 | 34 | namespace Ui { 35 | class MainWindow; 36 | } 37 | 38 | class QSQLiteTableView; 39 | class QSQLiteQueryWindow; 40 | 41 | class MainWindow : public QMainWindow 42 | { 43 | Q_OBJECT 44 | 45 | public: 46 | explicit MainWindow(QWidget *parent = 0); 47 | ~MainWindow(); 48 | 49 | CSQLite3DB* GetCurSQLite3DB() 50 | { 51 | return m_pCurSQLite3DB; 52 | } 53 | 54 | protected: 55 | void dragEnterEvent(QDragEnterEvent* e); 56 | void dropEvent(QDropEvent* e); 57 | 58 | private: 59 | Ui::MainWindow *ui; 60 | 61 | signals: 62 | void signalSQLiteQuery(const QString& sql); 63 | 64 | private Q_SLOTS: 65 | void OnTreeViewClick(const QModelIndex& index); 66 | void onProcessFinished(int ret); 67 | 68 | void onOpenActionTriggered(); 69 | void onCloseActionTriggered(); 70 | void onCheckActionTriggered(); 71 | void onVacuumActionTriggered(); 72 | void onAboutActionTriggered(); 73 | 74 | private: 75 | bool openDatabaseFile(const QString& path); 76 | 77 | private: 78 | // Menu and Tool 79 | QAction* m_pOpenAction; 80 | QAction* m_pCloseAction; 81 | QAction* m_pCheckAction; 82 | QAction* m_pVacuumAction; 83 | QAction* m_pAboutAction; 84 | 85 | 86 | // QTreeView at left 87 | QSQLiteMasterTreeView* m_pTreeView; 88 | QStandardItemModel* m_pTreeViewModel; 89 | 90 | // QTabWidget with sub widget 91 | QTabWidget* m_pTabWidget; 92 | 93 | HexWindow* m_pHexWindow; 94 | QTableWidget* m_pDatabase; 95 | QSQLiteQueryWindow* m_pSQL; 96 | DataWindow* m_pData; 97 | QTableWidget* m_pDesign; 98 | QTextEdit* m_pDDL; 99 | GraphWindow* m_pGraph; 100 | 101 | // QSplitter 102 | QSplitter* m_pSplitter; 103 | 104 | // sqlite3tools 105 | QMap m_mapSqlite3DBs; 106 | CSQLite3DB* m_pCurSQLite3DB; 107 | }; 108 | 109 | #endif // MAINWINDOW_H 110 | -------------------------------------------------------------------------------- /SQLiteExplorer/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 714 10 | 519 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 0 23 | 0 24 | 714 25 | 17 26 | 27 | 28 | 29 | 30 | 31 | TopToolBarArea 32 | 33 | 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /SQLiteExplorer/pixitem.cpp: -------------------------------------------------------------------------------- 1 | #include "pixitem.h" 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | //构造函数初始化了变量pix 16 | PixItem::PixItem(QWidget *parent) 17 | { 18 | setAcceptDrops(true); //设置可拖拽 19 | m_scaleValue = 0; 20 | m_isMove = false; 21 | } 22 | 23 | void PixItem::setPixmap(const QPixmap &pixmap) 24 | { 25 | pix = pixmap; 26 | setScale(1); 27 | } 28 | 29 | //实现自己的图元边界函数 30 | QRectF PixItem::boundingRect() const 31 | { 32 | return QRectF(-pix.width() / 2, -pix.height() / 2, 33 | pix.width(), pix.height()); 34 | } 35 | 36 | //只需QPainter的drawPixmap()函数将图元图片绘出即可 37 | void PixItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, 38 | QWidget *) 39 | { 40 | painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix); 41 | QRectF rc(-pix.width() / 2, -pix.height() / 2, pix.width(), pix.height()); 42 | painter->drawRect(rc); 43 | } 44 | 45 | //鼠标点击事件 局部缩放 46 | void PixItem::mousePressEvent(QGraphicsSceneMouseEvent *event) 47 | { 48 | m_startPos = event->pos(); 49 | m_isMove = true; 50 | 51 | int scaleValue = m_scaleValue; 52 | if(m_zoomState == ZOOM_IN) //局部放大 53 | { 54 | scaleValue++; 55 | } 56 | else if(m_zoomState == ZOOM_OUT) //局部缩小 57 | { 58 | scaleValue--; 59 | } 60 | 61 | if (scaleValue > ZOOM_IN_TIMES || scaleValue < ZOOM_OUT_TIMES) 62 | return; 63 | 64 | if (m_scaleValue != scaleValue) 65 | { 66 | setTransformOriginPoint(event->pos().x(), event->pos().y()); 67 | } 68 | m_scaleValue = scaleValue; 69 | qreal s; 70 | //实现局部缩放 71 | if(m_scaleValue > 0) 72 | { 73 | s = pow(1.1, m_scaleValue); //放大 计算x的y方次 参数都是double类型 74 | }else 75 | { 76 | s = pow(1 / 1.1, -m_scaleValue); //缩小 77 | } 78 | //qDebug() << "mousePressEvent: s =" << s << ", BoundingRect =" << boundingRect() << ", startPos =" << m_startPos; 79 | setScale(s); 80 | } 81 | 82 | void PixItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 83 | { 84 | if(m_isMove) 85 | { 86 | QPointF point = event->pos() - m_startPos; 87 | // QRectF brect = boundingRect(); 88 | // if(point.rx() < brect.left()) 89 | // point.setX(brect.left()); 90 | // if(point.rx() > brect.right()) 91 | // point.setX(brect.right()); 92 | // if(point.ry() < brect.top()) 93 | // point.setY(brect.top()); 94 | // if(point.ry() > brect.bottom()) 95 | // point.setY(brect.bottom()); 96 | 97 | moveBy(point.x(), point.y()); 98 | } 99 | } 100 | 101 | void PixItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) 102 | { 103 | m_isMove = false; 104 | } 105 | 106 | //使用滚轮整体缩放 107 | void PixItem::wheelEvent(QGraphicsSceneWheelEvent *event) 108 | { 109 | setZoomState(NO_STATE); 110 | 111 | int scaleValue = m_scaleValue; 112 | if(event->delta() > 0) //delta()为正,滚轮向上滚 113 | { 114 | scaleValue++; 115 | } 116 | else 117 | { 118 | scaleValue--; 119 | } 120 | 121 | if (scaleValue > ZOOM_IN_TIMES || scaleValue < ZOOM_OUT_TIMES) 122 | return; 123 | 124 | m_scaleValue = scaleValue; 125 | qreal s; 126 | if(m_scaleValue > 0) 127 | { 128 | s = pow(1.1, m_scaleValue); //放大 计算x的y方次 参数都是double类型 129 | } 130 | else 131 | { 132 | s = pow(1 / 1.1, -m_scaleValue); //缩小 133 | } 134 | //qDebug() << "wheelEvent: s=" << s << ", m_scaleValue = " << m_scaleValue; 135 | setScale(s); 136 | setTransformOriginPoint(event->pos().x(), event->pos().y()); 137 | } 138 | 139 | //从widget获取的缩放值,用于同步滚轮和按键 140 | void PixItem::setScaleValue(const int &scaleValue) 141 | { 142 | if (scaleValue > ZOOM_IN_TIMES || scaleValue < ZOOM_OUT_TIMES) 143 | return; 144 | 145 | m_scaleValue = scaleValue; 146 | 147 | qreal s; 148 | if(m_scaleValue > 0) 149 | { 150 | s = pow(1.1, m_scaleValue); //放大 计算x的y方次 参数都是double类型 151 | } 152 | else 153 | { 154 | s = pow(1 / 1.1, -m_scaleValue); //缩小 155 | } 156 | 157 | //qDebug() << "setScaleValue:" << s; 158 | setScale(s); 159 | } 160 | 161 | void PixItem::setZoomState(const int &zoomState) 162 | { 163 | m_zoomState = zoomState; 164 | if (m_zoomState == RESET) 165 | { 166 | m_scaleValue = 0; 167 | //qDebug() << "setZoomState:" << 1; 168 | setScale(1); 169 | setTransformOriginPoint(0, 0); 170 | } 171 | } 172 | 173 | int PixItem::getScaleValue() const 174 | { 175 | return m_scaleValue; 176 | } 177 | 178 | 179 | MyGraphicsView::MyGraphicsView(QWidget *parent) 180 | : QGraphicsView(parent) 181 | { 182 | m_scalingOffset=1; 183 | m_isMove = false; 184 | } 185 | 186 | MyGraphicsView::~MyGraphicsView() 187 | { 188 | 189 | } 190 | 191 | void MyGraphicsView::magnify() 192 | { 193 | if(m_scalingOffset>=10.0) 194 | return; 195 | 196 | m_scalingOffset*=1.1; 197 | scaling(1.1); 198 | } 199 | 200 | void MyGraphicsView::shrink() 201 | { 202 | if(m_scalingOffset<=0.1) 203 | return; 204 | 205 | m_scalingOffset*=0.9; 206 | scaling(0.9); 207 | } 208 | 209 | void MyGraphicsView::scaling(qreal scaleFactor) 210 | { 211 | //qDebug()<sceneRect() << " ScaleFactor = " << scaleFactor; 212 | scale(scaleFactor,scaleFactor); 213 | } 214 | 215 | //void MyGraphicsView::mousePressEvent(QMouseEvent *event) 216 | //{ 217 | // m_startPos = event->pos(); 218 | // m_isMove = true; 219 | //} 220 | 221 | //void MyGraphicsView::mouseMoveEvent(QMouseEvent *event) 222 | //{ 223 | // if(m_isMove) 224 | // { 225 | // QPointF point = event->pos() - m_startPos; 226 | // //moveBy(point.x(), point.y()); 227 | // move(point.x(), point.y()); 228 | // } 229 | //} 230 | 231 | //void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event) 232 | //{ 233 | // m_isMove = false; 234 | //} 235 | 236 | void MyGraphicsView::wheelEvent(QWheelEvent *event) 237 | { 238 | QPoint sroll=event->angleDelta(); 239 | //qDebug() << "wheelEvent: " << sroll; 240 | sroll.y()>0?magnify():shrink(); 241 | } 242 | -------------------------------------------------------------------------------- /SQLiteExplorer/pixitem.h: -------------------------------------------------------------------------------- 1 | #ifndef MYGRAPHICSVIEW_H 2 | #define MYGRAPHICSVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | QT_BEGIN_NAMESPACE 16 | class QWheelEvent; 17 | QT_END_NAMESPACE 18 | 19 | enum Enum_ZoomState{ 20 | NO_STATE, 21 | RESET, 22 | ZOOM_IN, 23 | ZOOM_OUT 24 | }; 25 | 26 | enum Enum_ZoomTimes{ 27 | ZOOM_IN_TIMES = 10, 28 | ZOOM_OUT_TIMES = -10, 29 | }; 30 | 31 | class PixItem : public QGraphicsItem 32 | { 33 | public: 34 | PixItem(QWidget* parent = 0); //构造函数初始化了变量pix 35 | void setPixmap(const QPixmap& pixmap); 36 | 37 | QRectF boundingRect() const; //实现自己的boundingRect 图元边界方法,完成以图元坐标系为基础增加两个像素点的冗余的工作 38 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); //重画图形函数 39 | 40 | void wheelEvent(QGraphicsSceneWheelEvent *event); 41 | void setZoomState(const int &zoomState); 42 | 43 | void mousePressEvent(QGraphicsSceneMouseEvent *event); 44 | void mouseMoveEvent(QGraphicsSceneMouseEvent *event); 45 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); 46 | 47 | int getScaleValue() const; 48 | void setScaleValue(const int &); 49 | 50 | private: 51 | qreal m_scaleValue; //缩放值 52 | 53 | QPixmap pix; //作为图元显示的图片 54 | int m_zoomState; 55 | 56 | bool m_isMove; 57 | QPointF m_startPos; 58 | }; 59 | 60 | 61 | class MyGraphicsView : public QGraphicsView 62 | { 63 | Q_OBJECT 64 | public: 65 | explicit MyGraphicsView(QWidget *parent = 0); 66 | ~MyGraphicsView(); 67 | 68 | protected: 69 | void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; 70 | void magnify(); 71 | void shrink(); 72 | void scaling(qreal scaleFactor); 73 | 74 | // void mousePressEvent(QMouseEvent *event); 75 | // void mouseMoveEvent(QMouseEvent *event); 76 | // void mouseReleaseEvent(QMouseEvent *event); 77 | 78 | private: 79 | qreal m_scalingOffset; 80 | bool m_isMove; 81 | QPointF m_startPos; 82 | }; 83 | 84 | #endif // MYGRAPHICSVIEW_H 85 | -------------------------------------------------------------------------------- /SQLiteExplorer/qsqlitetableview.cpp: -------------------------------------------------------------------------------- 1 | #include "qsqlitetableview.h" 2 | #include "mainwindow.h" 3 | #include 4 | #include 5 | #include 6 | 7 | QSQLiteTableView::QSQLiteTableView(QWidget *parent) 8 | : QTableWidget(parent) 9 | , m_pCurSQLite3DB(nullptr) 10 | , m_rowThresh(100) 11 | { 12 | // MainWindow* pMainWindow = qobject_cast(parent); 13 | // if (pMainWindow) 14 | // { 15 | // m_pParent = pMainWindow; 16 | // } 17 | 18 | QHeaderView *headers = horizontalHeader(); 19 | //SortIndicator为水平标题栏文字旁边的三角指示器 20 | headers->setSortIndicator(0, Qt::AscendingOrder); 21 | headers->setSortIndicatorShown(true); 22 | connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); 23 | } 24 | 25 | void QSQLiteTableView::onSQLiteQueryReceived(const QString &sql) 26 | { 27 | if (!m_pCurSQLite3DB) 28 | { 29 | return; 30 | } 31 | 32 | clear(); 33 | setColumnCount(0); 34 | setRowCount(0); 35 | m_rowThresh = 100; 36 | 37 | try 38 | { 39 | string s = sql.toStdString(); 40 | m_curQuery = m_pCurSQLite3DB->execQuery(s.c_str()); 41 | CppSQLite3Query& q = m_curQuery; 42 | 43 | QStringList headers; 44 | for(int i=0; isetText(QString::fromStdString(q.getStringField(col))); 59 | setItem(rowCount()-1, col, name); 60 | } 61 | q.nextRow(); 62 | if(rowCount() >= m_rowThresh) 63 | { 64 | break; 65 | } 66 | } 67 | 68 | QString msg; 69 | if(!q.eof()) 70 | { 71 | msg = QString("数据过多,已加载%1条记录").arg(rowCount()); 72 | } 73 | else 74 | { 75 | msg = QString("数据加载完成,共加载%1条记录").arg(rowCount()); 76 | } 77 | emit dataLoaded(msg); 78 | //qDebug() << msg; 79 | } 80 | catch(CppSQLite3Exception& e) 81 | { 82 | QMessageBox::information(this, tr("SQLiteExplorer"), QString::fromStdString(e.errorMessage())); 83 | } 84 | } 85 | 86 | void QSQLiteTableView::onValueChanged(int value) 87 | { 88 | // qDebug() << "value =" << value << ", VSBar Max =" << verticalScrollBar()->maximum() 89 | // << ", m_rowThresh =" << m_rowThresh; 90 | if(value == verticalScrollBar()->maximum() && !m_curQuery.eof()) 91 | { 92 | //qDebug() << "Enter "; 93 | m_rowThresh *= 2; 94 | CppSQLite3Query& q = m_curQuery; 95 | while (!q.eof()) 96 | { 97 | insertRow(rowCount()); 98 | for(int col=0; colsetText(QString::fromStdString(q.getStringField(col))); 102 | setItem(rowCount()-1, col, name); 103 | } 104 | q.nextRow(); 105 | if(rowCount() >= m_rowThresh) 106 | { 107 | break; 108 | } 109 | } 110 | QString msg; 111 | if(!q.eof()) 112 | { 113 | msg = QString("数据过多,已加载%1条记录").arg(rowCount()); 114 | } 115 | else 116 | { 117 | msg = QString("数据加载完成,共加载%1条记录").arg(rowCount()); 118 | } 119 | emit dataLoaded(msg); 120 | //qDebug() << msg; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /SQLiteExplorer/qsqlitetableview.h: -------------------------------------------------------------------------------- 1 | #ifndef QSQLITETABLEVIEW_H 2 | #define QSQLITETABLEVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "SQLite3DB.h" 9 | class MainWindow; 10 | 11 | 12 | class QSQLiteTableView : public QTableWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | QSQLiteTableView(QWidget *parent = 0); 17 | 18 | CSQLite3DB* SetDb(CSQLite3DB* pDb) 19 | { 20 | m_pCurSQLite3DB = pDb; 21 | } 22 | 23 | signals: 24 | void dataLoaded(const QString& msg); 25 | 26 | public slots: 27 | void onSQLiteQueryReceived(const QString& sql); 28 | void onValueChanged(int value); 29 | 30 | private: 31 | //MainWindow* m_pParent; 32 | CSQLite3DB* m_pCurSQLite3DB; 33 | CppSQLite3Query m_curQuery; 34 | int m_rowThresh; 35 | }; 36 | 37 | #endif // QSQLITETABLEVIEW_H 38 | -------------------------------------------------------------------------------- /SQLiteExplorer/ui/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/0.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/1.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/10.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/11.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/12.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/13.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/14.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/15.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/16.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/17.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/18.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/19.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/2.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/3.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/4.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/5.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/6.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/7.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/8.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/9.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/app.ico -------------------------------------------------------------------------------- /SQLiteExplorer/ui/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/app.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/db.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/find.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/freelist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/freelist.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/index.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/index.jpg -------------------------------------------------------------------------------- /SQLiteExplorer/ui/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/info.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/new.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/question.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/setting.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/table.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/trigger.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui/view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/SQLiteExplorer/ui/view.png -------------------------------------------------------------------------------- /SQLiteExplorer/ui_icon.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | ui/db.png 4 | ui/table.png 5 | ui/index.jpg 6 | ui/trigger.png 7 | ui/view.png 8 | ui/freelist.png 9 | 10 | 11 | ui/find.png 12 | ui/info.png 13 | ui/new.png 14 | ui/question.png 15 | ui/setting.png 16 | 17 | 18 | ui/1.png 19 | ui/2.png 20 | ui/3.png 21 | ui/4.png 22 | ui/5.png 23 | ui/6.png 24 | ui/7.png 25 | ui/8.png 26 | ui/9.png 27 | ui/10.png 28 | ui/11.png 29 | ui/12.png 30 | ui/13.png 31 | ui/14.png 32 | ui/15.png 33 | ui/16.png 34 | ui/17.png 35 | ui/18.png 36 | ui/19.png 37 | ui/0.png 38 | ui/app.png 39 | 40 | 41 | -------------------------------------------------------------------------------- /SQLiteExplorer/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::wstring; 8 | using std::vector; 9 | 10 | typedef unsigned char uint8_t; 11 | typedef signed char int8_t; 12 | 13 | typedef unsigned short uint16_t; 14 | typedef signed short int16_t; 15 | 16 | typedef unsigned int uint32_t; 17 | typedef signed int int32_t; 18 | 19 | typedef unsigned long long uint64_t; 20 | typedef signed long long int64_t; 21 | typedef int64_t i64; 22 | 23 | int StrToInt(const char* str); 24 | int64_t StrToInt64(const char* str); 25 | 26 | string StrUpper(const string& text); 27 | string StrLower(const string& text); 28 | 29 | int StrPos(const string& text, unsigned int start, const string& needle); 30 | vector StrSplit(const string& src, const string& split); 31 | 32 | 33 | /*! 34 | 将UTF8字符串转换成本地字符串 35 | @param pText UTF8字符串 36 | @return 本地字符串 37 | */ 38 | string utf8_to_local(const char* pText); 39 | 40 | /*! 41 | @param pText 本地字符串 42 | @return UTF8字符串 43 | */ 44 | string local_to_utf8(const char* pText); 45 | 46 | /*! 47 | 将UTF8字符串转换成UNICODE字符串 48 | @param pText UTF8字符串 49 | @return UNICODE字符串 50 | */ 51 | wstring utf8_to_wide(const char* pText); 52 | 53 | /*! 54 | @param pText UNICODE字符串 55 | @return UTF8字符串 56 | */ 57 | string wide_to_utf8(const wchar_t* pText); 58 | 59 | string TrimLeft(const string& text, const string& chars); 60 | 61 | string TrimRight(const string& text, const string& chars); 62 | 63 | string Trim(const string& text, const string& chars); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /SQLiteSolution.pro: -------------------------------------------------------------------------------- 1 | SUBDIRS += sqlite3 2 | #SUBDIRS += sqlite3tools 3 | #SUBDIRS += qtpropertybrowser 4 | SUBDIRS += SQLiteExplorer 5 | 6 | QMAKE_CXXFLAGS += /MP 7 | 8 | CONFIG += ordered 9 | TEMPLATE = subdirs 10 | 11 | -------------------------------------------------------------------------------- /art/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/1.png -------------------------------------------------------------------------------- /art/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/2.png -------------------------------------------------------------------------------- /art/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/3.png -------------------------------------------------------------------------------- /art/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/4.png -------------------------------------------------------------------------------- /art/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/5.png -------------------------------------------------------------------------------- /art/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/6.png -------------------------------------------------------------------------------- /art/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/7.png -------------------------------------------------------------------------------- /art/FreeListTrunk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/FreeListTrunk.jpg -------------------------------------------------------------------------------- /art/FreelistGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/FreelistGraph.jpg -------------------------------------------------------------------------------- /art/FreelistLeaf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/FreelistLeaf.jpg -------------------------------------------------------------------------------- /art/GraphViz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/GraphViz.jpg -------------------------------------------------------------------------------- /art/GraphWidget.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/GraphWidget.jpg -------------------------------------------------------------------------------- /art/HexWindow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/HexWindow.jpg -------------------------------------------------------------------------------- /art/IndexGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/IndexGraph.jpg -------------------------------------------------------------------------------- /art/IndexInterior.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/IndexInterior.jpg -------------------------------------------------------------------------------- /art/IndexLeaf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/IndexLeaf.jpg -------------------------------------------------------------------------------- /art/TableGraph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/TableGraph.jpg -------------------------------------------------------------------------------- /art/TableInterior.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/TableInterior.jpg -------------------------------------------------------------------------------- /art/TableLeaf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/art/TableLeaf.jpg -------------------------------------------------------------------------------- /sqlite3/sqlite3.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | sqlite3_aggregate_context 3 | sqlite3_aggregate_count 4 | sqlite3_auto_extension 5 | sqlite3_backup_finish 6 | sqlite3_backup_init 7 | sqlite3_backup_pagecount 8 | sqlite3_backup_remaining 9 | sqlite3_backup_step 10 | sqlite3_bind_blob 11 | sqlite3_bind_blob64 12 | sqlite3_bind_double 13 | sqlite3_bind_int 14 | sqlite3_bind_int64 15 | sqlite3_bind_null 16 | sqlite3_bind_parameter_count 17 | sqlite3_bind_parameter_index 18 | sqlite3_bind_parameter_name 19 | sqlite3_bind_pointer 20 | sqlite3_bind_text 21 | sqlite3_bind_text16 22 | sqlite3_bind_text64 23 | sqlite3_bind_value 24 | sqlite3_bind_zeroblob 25 | sqlite3_bind_zeroblob64 26 | sqlite3_blob_bytes 27 | sqlite3_blob_close 28 | sqlite3_blob_open 29 | sqlite3_blob_read 30 | sqlite3_blob_reopen 31 | sqlite3_blob_write 32 | sqlite3_busy_handler 33 | sqlite3_busy_timeout 34 | sqlite3_cancel_auto_extension 35 | sqlite3_changes 36 | sqlite3_clear_bindings 37 | sqlite3_close 38 | sqlite3_close_v2 39 | sqlite3_collation_needed 40 | sqlite3_collation_needed16 41 | sqlite3_column_blob 42 | sqlite3_column_bytes 43 | sqlite3_column_bytes16 44 | sqlite3_column_count 45 | sqlite3_column_database_name 46 | sqlite3_column_database_name16 47 | sqlite3_column_decltype 48 | sqlite3_column_decltype16 49 | sqlite3_column_double 50 | sqlite3_column_int 51 | sqlite3_column_int64 52 | sqlite3_column_name 53 | sqlite3_column_name16 54 | sqlite3_column_origin_name 55 | sqlite3_column_origin_name16 56 | sqlite3_column_table_name 57 | sqlite3_column_table_name16 58 | sqlite3_column_text 59 | sqlite3_column_text16 60 | sqlite3_column_type 61 | sqlite3_column_value 62 | sqlite3_commit_hook 63 | sqlite3_compileoption_get 64 | sqlite3_compileoption_used 65 | sqlite3_complete 66 | sqlite3_complete16 67 | sqlite3_config 68 | sqlite3_context_db_handle 69 | sqlite3_create_collation 70 | sqlite3_create_collation16 71 | sqlite3_create_collation_v2 72 | sqlite3_create_function 73 | sqlite3_create_function16 74 | sqlite3_create_function_v2 75 | sqlite3_create_module 76 | sqlite3_create_module_v2 77 | sqlite3_data_count 78 | sqlite3_db_cacheflush 79 | sqlite3_db_config 80 | sqlite3_db_filename 81 | sqlite3_db_handle 82 | sqlite3_db_mutex 83 | sqlite3_db_readonly 84 | sqlite3_db_release_memory 85 | sqlite3_db_status 86 | sqlite3_declare_vtab 87 | sqlite3_enable_load_extension 88 | sqlite3_enable_shared_cache 89 | sqlite3_errcode 90 | sqlite3_errmsg 91 | sqlite3_errmsg16 92 | sqlite3_errstr 93 | sqlite3_exec 94 | sqlite3_expanded_sql 95 | sqlite3_expired 96 | sqlite3_extended_errcode 97 | sqlite3_extended_result_codes 98 | sqlite3_file_control 99 | sqlite3_finalize 100 | sqlite3_free 101 | sqlite3_free_table 102 | sqlite3_get_autocommit 103 | sqlite3_get_auxdata 104 | sqlite3_get_table 105 | sqlite3_global_recover 106 | sqlite3_initialize 107 | sqlite3_interrupt 108 | sqlite3_last_insert_rowid 109 | sqlite3_libversion 110 | sqlite3_libversion_number 111 | sqlite3_limit 112 | sqlite3_load_extension 113 | sqlite3_log 114 | sqlite3_malloc 115 | sqlite3_malloc64 116 | sqlite3_memory_alarm 117 | sqlite3_memory_highwater 118 | sqlite3_memory_used 119 | sqlite3_mprintf 120 | sqlite3_msize 121 | sqlite3_mutex_alloc 122 | sqlite3_mutex_enter 123 | sqlite3_mutex_free 124 | sqlite3_mutex_leave 125 | sqlite3_mutex_try 126 | sqlite3_next_stmt 127 | sqlite3_open 128 | sqlite3_open16 129 | sqlite3_open_v2 130 | sqlite3_os_end 131 | sqlite3_os_init 132 | sqlite3_overload_function 133 | sqlite3_prepare 134 | sqlite3_prepare16 135 | sqlite3_prepare16_v2 136 | sqlite3_prepare16_v3 137 | sqlite3_prepare_v2 138 | sqlite3_prepare_v3 139 | sqlite3_profile 140 | sqlite3_progress_handler 141 | sqlite3_randomness 142 | sqlite3_realloc 143 | sqlite3_realloc64 144 | sqlite3_release_memory 145 | sqlite3_reset 146 | sqlite3_reset_auto_extension 147 | sqlite3_result_blob 148 | sqlite3_result_blob64 149 | sqlite3_result_double 150 | sqlite3_result_error 151 | sqlite3_result_error16 152 | sqlite3_result_error_code 153 | sqlite3_result_error_nomem 154 | sqlite3_result_error_toobig 155 | sqlite3_result_int 156 | sqlite3_result_int64 157 | sqlite3_result_null 158 | sqlite3_result_pointer 159 | sqlite3_result_subtype 160 | sqlite3_result_text 161 | sqlite3_result_text16 162 | sqlite3_result_text16be 163 | sqlite3_result_text16le 164 | sqlite3_result_text64 165 | sqlite3_result_value 166 | sqlite3_result_zeroblob 167 | sqlite3_result_zeroblob64 168 | sqlite3_rollback_hook 169 | sqlite3_rtree_geometry_callback 170 | sqlite3_rtree_query_callback 171 | sqlite3_set_authorizer 172 | sqlite3_set_auxdata 173 | sqlite3_set_last_insert_rowid 174 | sqlite3_shutdown 175 | sqlite3_sleep 176 | sqlite3_snprintf 177 | sqlite3_soft_heap_limit 178 | sqlite3_soft_heap_limit64 179 | sqlite3_sourceid 180 | sqlite3_sql 181 | sqlite3_status 182 | sqlite3_status64 183 | sqlite3_step 184 | sqlite3_stmt_busy 185 | sqlite3_stmt_readonly 186 | sqlite3_stmt_status 187 | sqlite3_strglob 188 | sqlite3_stricmp 189 | sqlite3_strlike 190 | sqlite3_strnicmp 191 | sqlite3_system_errno 192 | sqlite3_table_column_metadata 193 | sqlite3_test_control 194 | sqlite3_thread_cleanup 195 | sqlite3_threadsafe 196 | sqlite3_total_changes 197 | sqlite3_trace 198 | sqlite3_trace_v2 199 | sqlite3_transfer_bindings 200 | sqlite3_update_hook 201 | sqlite3_uri_boolean 202 | sqlite3_uri_int64 203 | sqlite3_uri_parameter 204 | sqlite3_user_data 205 | sqlite3_value_blob 206 | sqlite3_value_bytes 207 | sqlite3_value_bytes16 208 | sqlite3_value_double 209 | sqlite3_value_dup 210 | sqlite3_value_free 211 | sqlite3_value_int 212 | sqlite3_value_int64 213 | sqlite3_value_numeric_type 214 | sqlite3_value_pointer 215 | sqlite3_value_subtype 216 | sqlite3_value_text 217 | sqlite3_value_text16 218 | sqlite3_value_text16be 219 | sqlite3_value_text16le 220 | sqlite3_value_type 221 | sqlite3_vfs_find 222 | sqlite3_vfs_register 223 | sqlite3_vfs_unregister 224 | sqlite3_vmprintf 225 | sqlite3_vsnprintf 226 | sqlite3_vtab_config 227 | sqlite3_vtab_on_conflict 228 | sqlite3_wal_autocheckpoint 229 | sqlite3_wal_checkpoint 230 | sqlite3_wal_checkpoint_v2 231 | sqlite3_wal_hook 232 | sqlite3_win32_is_nt 233 | sqlite3_win32_mbcs_to_utf8 234 | sqlite3_win32_mbcs_to_utf8_v2 235 | sqlite3_win32_set_directory 236 | sqlite3_win32_sleep 237 | sqlite3_win32_unicode_to_utf8 238 | sqlite3_win32_utf8_to_mbcs 239 | sqlite3_win32_utf8_to_mbcs_v2 240 | sqlite3_win32_utf8_to_unicode 241 | sqlite3_win32_write_debug 242 | -------------------------------------------------------------------------------- /sqlite3/sqlite3.pro: -------------------------------------------------------------------------------- 1 | TARGET = sqlite3 2 | TEMPLATE = lib 3 | DESTDIR = $$PWD/../bin 4 | 5 | #message($$PWD) 6 | 7 | HEADERS = sqlite3.h 8 | 9 | SOURCES = sqlite3.c 10 | -------------------------------------------------------------------------------- /test/test.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hawkchch/SQLiteExplorer/5738e7ced5694873ca6f347c9e58181f3a061aa8/test/test.db --------------------------------------------------------------------------------