From ee9de663805c5f4f96390804c692a56aec2b32d8 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Fri, 24 Jun 2011 13:05:56 +0200 Subject: [PATCH] Initial Import. --- IoSQL.pro | 23 ++ IoSQL.qrc | 26 ++ Makefile | 310 ++++++++++++++++ images/general/refresh.png | Bin 0 -> 1283 bytes images/run-build.png | Bin 0 -> 1208 bytes images/server-database-deregister.png | Bin 0 -> 1513 bytes images/server-database-edit.png | Bin 0 -> 1573 bytes images/server-database-register.png | Bin 0 -> 770 bytes images/table/commit.png | Bin 0 -> 1313 bytes images/table/delete-column.png | Bin 0 -> 2097 bytes images/table/delete-row.png | Bin 0 -> 2097 bytes images/table/icon.png | Bin 0 -> 1179 bytes images/table/insert-column.png | Bin 0 -> 1244 bytes images/table/insert-row.png | Bin 0 -> 961 bytes images/table/list.png | Bin 0 -> 587 bytes images/table/rollback.png | Bin 0 -> 1221 bytes images/table/table.png | Bin 0 -> 2097 bytes images/view/list.png | Bin 0 -> 928 bytes images/view/view.png | Bin 0 -> 2097 bytes main.cpp | 10 + mainwindow.cpp | 498 ++++++++++++++++++++++++++ mainwindow.h | 50 +++ mainwindow.ui | 339 ++++++++++++++++++ registerdialog.cpp | 125 +++++++ registerdialog.h | 39 ++ registerdialog.ui | 199 ++++++++++ sqlform.cpp | 38 ++ sqlform.h | 24 ++ sqlform.ui | 50 +++ tableform.cpp | 158 ++++++++ tableform.h | 35 ++ tableform.ui | 330 +++++++++++++++++ 32 files changed, 2254 insertions(+) create mode 100644 IoSQL.pro create mode 100644 IoSQL.qrc create mode 100644 Makefile create mode 100644 images/general/refresh.png create mode 100644 images/run-build.png create mode 100644 images/server-database-deregister.png create mode 100644 images/server-database-edit.png create mode 100644 images/server-database-register.png create mode 100644 images/table/commit.png create mode 100644 images/table/delete-column.png create mode 100644 images/table/delete-row.png create mode 100644 images/table/icon.png create mode 100644 images/table/insert-column.png create mode 100644 images/table/insert-row.png create mode 100644 images/table/list.png create mode 100644 images/table/rollback.png create mode 100644 images/table/table.png create mode 100644 images/view/list.png create mode 100644 images/view/view.png create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 registerdialog.cpp create mode 100644 registerdialog.h create mode 100644 registerdialog.ui create mode 100644 sqlform.cpp create mode 100644 sqlform.h create mode 100644 sqlform.ui create mode 100644 tableform.cpp create mode 100644 tableform.h create mode 100644 tableform.ui diff --git a/IoSQL.pro b/IoSQL.pro new file mode 100644 index 0000000..a1da6f2 --- /dev/null +++ b/IoSQL.pro @@ -0,0 +1,23 @@ +# ------------------------------------------------- +# Project created by QtCreator 2010-02-10T18:56:54 +# ------------------------------------------------- +QT += network \ + sql +TARGET = IoSQL +TEMPLATE = app +SOURCES += main.cpp \ + mainwindow.cpp \ + registerdialog.cpp \ + tableform.cpp \ + sqlform.cpp +HEADERS += mainwindow.h \ + registerdialog.h \ + tableform.h \ + sqlform.h +FORMS += mainwindow.ui \ + registerdialog.ui \ + tableform.ui \ + sqlform.ui +RESOURCES += IoSQL.qrc +INCLUDEPATH += /usr/include/qt4/Qsci +LIBS += -lqscintilla2 diff --git a/IoSQL.qrc b/IoSQL.qrc new file mode 100644 index 0000000..0f2e64c --- /dev/null +++ b/IoSQL.qrc @@ -0,0 +1,26 @@ + + + images/table/delete-column.png + images/table/delete-row.png + images/table/commit.png + images/table/rollback.png + images/table/insert-column.png + images/table/insert-row.png + images/table/list.png + images/table/table.png + images/table/icon.png + images/run-build.png + + + images/server-database-register.png + images/server-database-deregister.png + images/server-database-edit.png + + + images/view/list.png + images/view/view.png + + + images/general/refresh.png + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bcf7429 --- /dev/null +++ b/Makefile @@ -0,0 +1,310 @@ +############################################################################# +# Makefile for building: IoSQL +# Generated by qmake (2.01a) (Qt 4.7.2) on: Wed Jun 22 13:31:58 2011 +# Project: IoSQL.pro +# Template: app +# Command: /usr/bin/qmake -spec /usr/share/qt4/mkspecs/linux-g++ CONFIG+=debug QMLJSDEBUGGER_PATH=/usr/share/qtcreator/qml/qmljsdebugger -o Makefile IoSQL.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -DQT_SQL_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED +CFLAGS = -pipe -g -Wall -W -D_REENTRANT $(DEFINES) +CXXFLAGS = -pipe -g -Wall -W -D_REENTRANT $(DEFINES) +INCPATH = -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I/usr/include/qt4/Qsci -I. -I. +LINK = g++ +LFLAGS = +LIBS = $(SUBLIBS) -L/usr/lib -lqscintilla2 -lQtSql -lQtGui -lQtNetwork -lQtCore -lpthread +AR = ar cqs +RANLIB = +QMAKE = /usr/bin/qmake +TAR = tar -cf +COMPRESS = gzip -9f +COPY = cp -f +SED = sed +COPY_FILE = $(COPY) +COPY_DIR = $(COPY) -r +STRIP = strip +INSTALL_FILE = install -m 644 -p +INSTALL_DIR = $(COPY_DIR) +INSTALL_PROGRAM = install -m 755 -p +DEL_FILE = rm -f +SYMLINK = ln -f -s +DEL_DIR = rmdir +MOVE = mv -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files + +SOURCES = main.cpp \ + mainwindow.cpp \ + registerdialog.cpp \ + tableform.cpp \ + sqlform.cpp moc_mainwindow.cpp \ + moc_registerdialog.cpp \ + moc_tableform.cpp \ + moc_sqlform.cpp \ + qrc_IoSQL.cpp +OBJECTS = main.o \ + mainwindow.o \ + registerdialog.o \ + tableform.o \ + sqlform.o \ + moc_mainwindow.o \ + moc_registerdialog.o \ + moc_tableform.o \ + moc_sqlform.o \ + qrc_IoSQL.o +DIST = /usr/share/qt4/mkspecs/common/g++.conf \ + /usr/share/qt4/mkspecs/common/unix.conf \ + /usr/share/qt4/mkspecs/common/linux.conf \ + /usr/share/qt4/mkspecs/qconfig.pri \ + /usr/share/qt4/mkspecs/modules/qt_phonon.pri \ + /usr/share/qt4/mkspecs/modules/qt_webkit_version.pri \ + /usr/share/qt4/mkspecs/features/qt_functions.prf \ + /usr/share/qt4/mkspecs/features/qt_config.prf \ + /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ + /usr/share/qt4/mkspecs/features/default_pre.prf \ + /usr/share/qt4/mkspecs/features/debug.prf \ + /usr/share/qt4/mkspecs/features/default_post.prf \ + /usr/share/qt4/mkspecs/features/warn_on.prf \ + /usr/share/qt4/mkspecs/features/qt.prf \ + /usr/share/qt4/mkspecs/features/unix/thread.prf \ + /usr/share/qt4/mkspecs/features/moc.prf \ + /usr/share/qt4/mkspecs/features/resources.prf \ + /usr/share/qt4/mkspecs/features/uic.prf \ + /usr/share/qt4/mkspecs/features/yacc.prf \ + /usr/share/qt4/mkspecs/features/lex.prf \ + /usr/share/qt4/mkspecs/features/include_source_dir.prf \ + IoSQL.pro +QMAKE_TARGET = IoSQL +DESTDIR = +TARGET = IoSQL + +first: all +####### Implicit rules + +.SUFFIXES: .o .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" + +####### Build rules + +all: Makefile $(TARGET) + +$(TARGET): ui_mainwindow.h ui_registerdialog.h ui_tableform.h ui_sqlform.h $(OBJECTS) + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) + +Makefile: IoSQL.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/g++.conf \ + /usr/share/qt4/mkspecs/common/unix.conf \ + /usr/share/qt4/mkspecs/common/linux.conf \ + /usr/share/qt4/mkspecs/qconfig.pri \ + /usr/share/qt4/mkspecs/modules/qt_phonon.pri \ + /usr/share/qt4/mkspecs/modules/qt_webkit_version.pri \ + /usr/share/qt4/mkspecs/features/qt_functions.prf \ + /usr/share/qt4/mkspecs/features/qt_config.prf \ + /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ + /usr/share/qt4/mkspecs/features/default_pre.prf \ + /usr/share/qt4/mkspecs/features/debug.prf \ + /usr/share/qt4/mkspecs/features/default_post.prf \ + /usr/share/qt4/mkspecs/features/warn_on.prf \ + /usr/share/qt4/mkspecs/features/qt.prf \ + /usr/share/qt4/mkspecs/features/unix/thread.prf \ + /usr/share/qt4/mkspecs/features/moc.prf \ + /usr/share/qt4/mkspecs/features/resources.prf \ + /usr/share/qt4/mkspecs/features/uic.prf \ + /usr/share/qt4/mkspecs/features/yacc.prf \ + /usr/share/qt4/mkspecs/features/lex.prf \ + /usr/share/qt4/mkspecs/features/include_source_dir.prf \ + /usr/lib/libQtSql.prl \ + /usr/lib/libQtGui.prl \ + /usr/lib/libQtNetwork.prl \ + /usr/lib/libQtCore.prl + $(QMAKE) -spec /usr/share/qt4/mkspecs/linux-g++ CONFIG+=debug QMLJSDEBUGGER_PATH=/usr/share/qtcreator/qml/qmljsdebugger -o Makefile IoSQL.pro +/usr/share/qt4/mkspecs/common/g++.conf: +/usr/share/qt4/mkspecs/common/unix.conf: +/usr/share/qt4/mkspecs/common/linux.conf: +/usr/share/qt4/mkspecs/qconfig.pri: +/usr/share/qt4/mkspecs/modules/qt_phonon.pri: +/usr/share/qt4/mkspecs/modules/qt_webkit_version.pri: +/usr/share/qt4/mkspecs/features/qt_functions.prf: +/usr/share/qt4/mkspecs/features/qt_config.prf: +/usr/share/qt4/mkspecs/features/exclusive_builds.prf: +/usr/share/qt4/mkspecs/features/default_pre.prf: +/usr/share/qt4/mkspecs/features/debug.prf: +/usr/share/qt4/mkspecs/features/default_post.prf: +/usr/share/qt4/mkspecs/features/warn_on.prf: +/usr/share/qt4/mkspecs/features/qt.prf: +/usr/share/qt4/mkspecs/features/unix/thread.prf: +/usr/share/qt4/mkspecs/features/moc.prf: +/usr/share/qt4/mkspecs/features/resources.prf: +/usr/share/qt4/mkspecs/features/uic.prf: +/usr/share/qt4/mkspecs/features/yacc.prf: +/usr/share/qt4/mkspecs/features/lex.prf: +/usr/share/qt4/mkspecs/features/include_source_dir.prf: +/usr/lib/libQtSql.prl: +/usr/lib/libQtGui.prl: +/usr/lib/libQtNetwork.prl: +/usr/lib/libQtCore.prl: +qmake: FORCE + @$(QMAKE) -spec /usr/share/qt4/mkspecs/linux-g++ CONFIG+=debug QMLJSDEBUGGER_PATH=/usr/share/qtcreator/qml/qmljsdebugger -o Makefile IoSQL.pro + +dist: + @$(CHK_DIR_EXISTS) .tmp/IoSQL1.0.0 || $(MKDIR) .tmp/IoSQL1.0.0 + $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/IoSQL1.0.0/ && $(COPY_FILE) --parents mainwindow.h registerdialog.h tableform.h sqlform.h .tmp/IoSQL1.0.0/ && $(COPY_FILE) --parents IoSQL.qrc .tmp/IoSQL1.0.0/ && $(COPY_FILE) --parents main.cpp mainwindow.cpp registerdialog.cpp tableform.cpp sqlform.cpp .tmp/IoSQL1.0.0/ && $(COPY_FILE) --parents mainwindow.ui registerdialog.ui tableform.ui sqlform.ui .tmp/IoSQL1.0.0/ && (cd `dirname .tmp/IoSQL1.0.0` && $(TAR) IoSQL1.0.0.tar IoSQL1.0.0 && $(COMPRESS) IoSQL1.0.0.tar) && $(MOVE) `dirname .tmp/IoSQL1.0.0`/IoSQL1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/IoSQL1.0.0 + + +clean:compiler_clean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) $(TARGET) + -$(DEL_FILE) Makefile + + +check: first + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_moc_header_make_all: moc_mainwindow.cpp moc_registerdialog.cpp moc_tableform.cpp moc_sqlform.cpp +compiler_moc_header_clean: + -$(DEL_FILE) moc_mainwindow.cpp moc_registerdialog.cpp moc_tableform.cpp moc_sqlform.cpp +moc_mainwindow.cpp: registerdialog.h \ + sqlform.h \ + mainwindow.h + /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) mainwindow.h -o moc_mainwindow.cpp + +moc_registerdialog.cpp: registerdialog.h + /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) registerdialog.h -o moc_registerdialog.cpp + +moc_tableform.cpp: tableform.h + /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) tableform.h -o moc_tableform.cpp + +moc_sqlform.cpp: sqlform.h + /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) sqlform.h -o moc_sqlform.cpp + +compiler_rcc_make_all: qrc_IoSQL.cpp +compiler_rcc_clean: + -$(DEL_FILE) qrc_IoSQL.cpp +qrc_IoSQL.cpp: IoSQL.qrc \ + images/general/refresh.png \ + images/run-build.png \ + images/table/rollback.png \ + images/table/commit.png \ + images/table/table.png \ + images/table/list.png \ + images/table/icon.png \ + images/table/delete-column.png \ + images/table/insert-row.png \ + images/table/insert-column.png \ + images/table/delete-row.png \ + images/view/list.png \ + images/view/view.png \ + images/server-database-edit.png \ + images/server-database-register.png \ + images/server-database-deregister.png + /usr/bin/rcc -name IoSQL IoSQL.qrc -o qrc_IoSQL.cpp + +compiler_image_collection_make_all: qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) qmake_image_collection.cpp +compiler_moc_source_make_all: +compiler_moc_source_clean: +compiler_uic_make_all: ui_mainwindow.h ui_registerdialog.h ui_tableform.h ui_sqlform.h +compiler_uic_clean: + -$(DEL_FILE) ui_mainwindow.h ui_registerdialog.h ui_tableform.h ui_sqlform.h +ui_mainwindow.h: mainwindow.ui + /usr/bin/uic-qt4 mainwindow.ui -o ui_mainwindow.h + +ui_registerdialog.h: registerdialog.ui + /usr/bin/uic-qt4 registerdialog.ui -o ui_registerdialog.h + +ui_tableform.h: tableform.ui + /usr/bin/uic-qt4 tableform.ui -o ui_tableform.h + +ui_sqlform.h: sqlform.ui + /usr/bin/uic-qt4 sqlform.ui -o ui_sqlform.h + +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_moc_header_clean compiler_rcc_clean compiler_uic_clean + +####### Compile + +main.o: main.cpp mainwindow.h \ + registerdialog.h \ + sqlform.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp + +mainwindow.o: mainwindow.cpp mainwindow.h \ + registerdialog.h \ + sqlform.h \ + ui_mainwindow.h \ + tableform.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o mainwindow.o mainwindow.cpp + +registerdialog.o: registerdialog.cpp registerdialog.h \ + ui_registerdialog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o registerdialog.o registerdialog.cpp + +tableform.o: tableform.cpp tableform.h \ + ui_tableform.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o tableform.o tableform.cpp + +sqlform.o: sqlform.cpp sqlform.h \ + ui_sqlform.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o sqlform.o sqlform.cpp + +moc_mainwindow.o: moc_mainwindow.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_mainwindow.o moc_mainwindow.cpp + +moc_registerdialog.o: moc_registerdialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_registerdialog.o moc_registerdialog.cpp + +moc_tableform.o: moc_tableform.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_tableform.o moc_tableform.cpp + +moc_sqlform.o: moc_sqlform.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_sqlform.o moc_sqlform.cpp + +qrc_IoSQL.o: qrc_IoSQL.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qrc_IoSQL.o qrc_IoSQL.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/images/general/refresh.png b/images/general/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..45b5535ce420dff6a52b31609225245a2174de59 GIT binary patch literal 1283 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 P00000NkvXXu0mjfqVVnQ literal 0 HcmV?d00001 diff --git a/images/server-database-edit.png b/images/server-database-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..9c315f384e3ad9e1d17924fa71e6957a29460bdf GIT binary patch literal 1573 zcmV+=2HN?FP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00hDS00hDTyw8vr00007bV*G`2igY# z3k(^tW+t%!00pH4h(r40r%P5Zny^W=`I$@m#ue>Fkv&SDOF3 zQF;c94n1 z9A`@i;N72eyoZ{JNM5(kA4D2jq4Nl21}5CS0t zj^iMN_ z@AKKiI;5ijrl^kXE+#o3qR{O0`zEbk*M%VNil9gg4c$Cb%sEU(w=+Oua5>2w;$ahREz zK?p%hOAC{elRS9vfOI-dHk*Zoce(L5ozrd85|sB=gytTvP^e(H|25} zP19(X|HwZ-Hpncx_`x^5ENFt3t|6{nyGA4u!M1JM+uKdQ-*3Cd#>O1Wvb?>$y=1dl zgb<`sDQw%OwY8PW$w^YF6ha90Hs9e_?-|%Oy!nd2Y&^}{+8U~=Qm@yE#bOi+1)mT? zQhIxPy}GX3#bQzJ>+56RzI~+AX~xILnV+9$c6OFXB*O0J{=uhn9>%7htwwu$yR9gS$Cb@ym1?!>>F)0S z{MUhOHj8PRTUU`vrC9mWFL>$nSq}HO@yTVPU2h=EGNn?9g@pwS!=SUXlexJ$uMk3! z4Z~2ny1HJiR;$|%9XiDJ?b|U7165U7UtectW(J?nN6@uIH1rw!;yNEr9A=~LC!J1H zEEd_ne?P%s5W_IIfB*hOGMT(A1Ln%gN~)=;X)qd%`tRJiLswT9$BrE%91hdk+Da%C z;-h?-h;ffO`(=*yze+qFCy_`XNfN`u!vq2Wa=Bb#czF0?sZ{z@285<*nfdwoVaIV| z9*-yHcDtpHjt)9HI=FZ59&2lB#G4~H4Tr(yBb&``ontgHSX^8j z2W;snn+gU3fnBj!?9B1w$G>sp$dR5*CgY1lB2qjaM^O~=`8?@#T12DKN-me1xOwyD zU#F+1Kd4r#vp{vzMV{$-(xy=cfJRxC1L1Hu>ht-&0yu_Y%xRjoXxnxLC~d;*ry>6V XU~Tyrms#ZX00000NkvXXu0mjfEKvvl literal 0 HcmV?d00001 diff --git a/images/server-database-register.png b/images/server-database-register.png new file mode 100644 index 0000000000000000000000000000000000000000..de59704a320c6b7085361c77a2c4bcaebfe0e3c0 GIT binary patch literal 770 zcmV+d1O5DoP)Px#32;bRa{vGY!T0%A)?L;(MX zkIcUS00M?dL_t&-83n;jZ&YO%0MPT^d)t`~f;3tnAlTB06-u~l4RnHdQl%)a1en^k^n%cRFZJtNGetb?KHGo0{{R(=<1r! z2eN}z%OCps2FPSGnM@{=VW703r5&Q!X;(F${cFyLri?0NDr6X_Jaxr{p;xOh#nP~r zo%BFu!KD4ZSK1}>+?umk@W_j1&1b`^IOS<1~yy_DeOaozN5(l@7RTQ3y@f)YYt8H87=B zk5rtfZI;jSGhX+=ZI9eHVXxep$8M->_{63S{lRuotmZEbm-8p)oO4_kVPV zim&Xq?NC{aX3b)2^q3}^`u4kP5iGl=F4ysoo@ozjQ52nSbD=)_rWsG%@X(SyUQk%K z=DMM67i`ompXsvqP_I!YBe=F zHIgPx`q{dMWL?t{xfQp{)o-p`e0*D(K(eE8bn2sb-+Sx$Qhg#FR#@>M_H~!1EuOdJt-|(ZvX%Q07*qoM6N<$f=QKX A(f|Me literal 0 HcmV?d00001 diff --git a/images/table/commit.png b/images/table/commit.png new file mode 100644 index 0000000000000000000000000000000000000000..16bdd61c1d5284958476b223243b7ccd3b49ffc3 GIT binary patch literal 1313 zcmV++1>X9JP)Px#32;bRa{vGvuK)lWuK`{fksJU300(qQO+^RU1`z=o8>NbS9RL6T24YJ`L;(K) z{{a7>y{D4^00f~)L_t(|+ND!#Oq*pGJ@5Cmw3O18LdPl?%Vh+L45$jsf*~^+L1!Wh zbCN8XL}N^h2{Gyq<3DG-#JKoF=Pk@RcS#6~5Tk~XU;@cdB7-n);~pU6QVOLllwMw+ z_f2Qg{ZOJO`9d0==RD^*&v~(LSYEWYeA@Lb^estwjpy;dVXJ%A_4*J$_1@3i{_Oc;{0kKP1H405fb2TgVQ2O^ z9t~q<#luVU^(f9Ubg4Dp*z!+Y*dOus_BQT`SFemBE?W?C0s$&WL_Y!+N9;BwG3c{q_ogHCp$FZl}bG1j^HlHuVLt%!!2t#O( zArj&IerxpQb8Y=I0KN}}LdOBf{2G0HR@Sy= zZf*_^hXa1U|05#SF>v(WUSw;&4P3kYB@`aPVb{ZWto}3vv^pJr`0yq8!v<(gb~vl6 zs5ihkk8vWtkG{76ysHtUam5aU!2q%XPZVY2M8{{)5s4+ujO?0bq*=_+Fa_iZ3`P^~ z-1rgR4KE!u2=BHZ0ArCzgnkF?AZQTB)YKHS*=(>{tq5`s&*m0rI;<8G)YLQ>Gi@;H zb@0cc;D!Sj8=Ju9c0kt9CoS68*uc`#lA1tFh8uQvc0d<~*=&}|1vb52|hY&Q8Iy1Tp4-`@|X(}_ce4vAWQ0x=au?RGmdGBQM-(bLl-wvd*LkB=iaHy0@> zDbfOwQ+S)2Ml!8i1O2P@mtE;OjO_i4&85u!lW+v+E>qVg$AU#x772$AL z4k;=slIq*q+C;>}AfA_($0%Jg6)NJOsHv2OI`T>ukk3M`Y@(w|wdAi5fXT^8tgo-5 zudh!=?Z}ZM^5~lPXt8&OtPCK4bs8V|oz zOl!;6T3K1i=?1L5y&W2jW^Z_S_?^zq&I?j;{MCsg#Auz4-QC?A2 z68Yvtz$mklnCci2iU0pbb{(IcoxLXR;dZ;h5C=^cN0Vs~C@wCpuBoXxMg%1kAsY=b zSS%KmtOyf9fK)F}OicVSFfhn;cA~vU|ryI#n9qs{%NcjC1 Xt5i}6fY$;g}~|8 z(SP(~M6C5C+Zs@{Qj?C|s@jF1rLlBVk;N&+N^vnoJBIrZag-JoJewCI9kFclqsRTp z@i==vWjGp6)4L+A;QlgV^bvsdQ!m%?OHV!dD)v6Qigp6xYe29_g|b$UzAsAX<3BnfO_zt-WB>2{5}p~>wherpG!*S z{p&OMivSOQ8fgNltE=lZkH-U&Bmv_b+-9?{_UhFSnZW=OHn3XpJkc@I2Kyr-8kTCB z)qptpM#tN^r@m@q-nH9nucRkK=5M$7<&3nEXMT33Lq|skzgN8F<%~~Ea17?8N&Gu^ zilG>UKYOZna8Gg~cVs`x&!0WVJJ;oMmb9GjUz4?4Run~SOI3rRZJK0Y<6{!D+ktQg)TnvD?G&uo$auOIhEbyCixgfWx2?98o#u&sU*uk5bCDO>6rondu=RsA) zdLS4T1qH6VaLzdb%w_}Qu}%n9RwCwtvp-w{*^9M+VltV8UKmSQFc1(pv@|yh#uQcK z)B-rVOY1^mjg4HHnd5wHoX;#JoCuwbM6mf!RPgf=EeEQ z!kkWUzxoES`dSDkE(ebEkWKefgB<*dA1R-Yr93*d$gu)Amnfgm9`NeGj+T}Nmgk-a z-}@iHQlC#uCYBQBn9hV^N$clBdGuls9G~iS%yS$a4ds~FariK3dHKM<=?5ccuoy?E3DDl0qe%k157h+?BT6$v4El~a0W5`z%2N91hC3T zwgqt$8)jyRoVJv|PP8E2h7&+LHLGixLY0uRKf!Gy$EmXflPU3_P7)@r>N zyCk9#v1@bwK#zIWZQ_`8kx&^jt}%^Kxr1yl7&{+HO&Gd;gW)|X!B4SfZRObLZRGUx zv_ozC$cc9xc)>hAy4w|N9?o*xjQ^S!IZsMSU_G)-4`)c4o1676{AmvDlmM(Q(RAZN ln~p8iE#XH(*9&d`TYq@_VArv#k_(iuv}ki-_lAn*zX0V^@)`gD literal 0 HcmV?d00001 diff --git a/images/table/delete-row.png b/images/table/delete-row.png new file mode 100644 index 0000000000000000000000000000000000000000..a15c8857cece3aa411b240e81220f7284968ddaf GIT binary patch literal 2097 zcmeHHZ%ma{82_F3zW2WOuLCPUQl~&=%TyXk>X=C&GA0311k*)2YHQ}4XdCfCM%qTR z=EnNsYHPHiNzqVHCt=)XVK%@OmyDJKTqW>!FBk8h_ulv3_w>A%D09#Ut#3Vd=RP~X z_nhB(p5J+%(@<2HXEP_80od}l$#+aIloQgHpR=j-sd&~bmCLl^ z-mGm&QgJy)n}6W&tIxnreQzaPtUFrLUe@H#qfHJ#SqUSIO>{{UmK1 z0LJ^BJjOaV&tyGAlm#=BK3fqBy}? zT3WcOs<*8JL{UT}68T4rF$O``Y~85rjMD^suUxiXXjhr_||wEq4p zcS3wF%>Mo{)%VbHeqwF9uOdBb!?BFjH|2*@dE*mn_KLC`LReA2`AmRXB!OUniVX;d zl^8e|1`^Sdk;$4?rymg>Tid?7uw?9L@w1PLiE%q$`?mL}7>Gm>W+K({UzrD^QD~G3 z(-A)N;qREXmcbVYAhYGuk6fN`cskx7?-&{MZe{Fkzu63?HZ^e`48|gaUJoG@0<&77 z`u*TKBBsH@AqW=2h=?1gu_!%8hYMCKS0*M|WOA}EIyTme(NVkJF<>{kTuwo8xge*c z!Ch7Xb$lG|=gZL^2trx83f_&`2=(^D{ZbW92W80d3*k*lhVSe-xQn)-qqCDa&G&Eq z^@ktd^Ncz>PIZ5ALL=287C>ZCO4ri$IXo}FiUsc;K{PH7Vowj)$S?5k*$2xjRfr}( z2w}hh+;lhwZ+}d6Vv9Ay8+BHlad=u&?AH(-LJraWsaOZUd4%9$xIE=|N_I-;E*1YH`Ds#HG zRs5zA$21NV6mahK(v%(@Q4gksAyFz?wZtw|Cy>SpB&!Xw-v_1>X`Kibk|Eg^aGxwQ zRf+UPWw}>3?X?RxZrE);pOZCxc8agd+N2%yr*(CnML}UPWYTrk=EAx!oX6A8m8=;C zWNI-_ltuw#iWafReRTWN({#}@g{;*qZcQUP<%KHG5YLOzKBGHgv5pQ4jOzk6o0aO8 zR3(i?jZklpG$CTau~_~Ll4OLc5=Q6Dhf&dC@j}th#I%rJ$HEB~#NL70+FG#E(o!Cw z&YLx@9YnoI-57}-q2cpk0%>iMBp8gw9<$kW$z(ELvREu%*VWZIXZikBuSNX7{r3tO VJ3RZBJFdn`EkCy~r!~8>{&y*G6k7lQ literal 0 HcmV?d00001 diff --git a/images/table/icon.png b/images/table/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6e66f718b4c79641fe1b5579a6d819eb1714c004 GIT binary patch literal 1179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=f!eQwFr$;k>+JY@lC{{R2~nScNO;WUGhk&)rtxeE;6zyDycv9V-0d-goT z@85qJEGKl)lP6E3@If4G zVn7p&nc&8d$pAUn`26{cXMX`JSfN&fLIyI22w-=P!!z-834mX>qJuc|4-BJ97zS+dmu4SS3j3^P6Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L011Qu011Qvs^VjL00007bV*G`2igJ< z4IUhwFk#gI00dk~L_t(I%cYciXjXL?$3N%1w_TiLV(R7%WM!q`0ujQ2qDYpNQb|HY zp^OOs$O!r)ThcZ}oHK}tbdeTCxMaFl=Ve;v4GOf(mA3|7R=Ta+yX}3?d){;V{ht0f z`Z_Z(?13N8;d?&c?;p>3e#hYd)QiC5Os*JPv0>J@S<}1vx_-U($F;Tm#jN4*1zI4|{pGv2IB|z^>n9wZ zZhT=-mVwlp!k7;X28$6U8o$ue(jxz?kB|8Jvuj#Jlx*wKk`gUzwmWxmEiEm=euS-v zhzK7c=6+N7mMNy|x&ZiofbR!Dz~z)SUae4UJ|`?FRpfG-8)*&52o7A=WoYpgo~nKt zGikDUbw9Cj!8zgn?3u zQ^yaIa-sml<8izo%%Q%nF8r8*7BA2uB2x9fCH;=b+uw^gzLwe_MJB8n4mn?o=ZDXLcB@sN=C9tztRyYd7EXmKBUDxBl-ZpYM2QVlr za3Qi%Rup_{e6=G%W2MWUWCBLNEUm3OjFFt{dhGAm$)J+}gu=pt+rf`jRdvsqxAc&0 zXQF~Z#c1sn97(TScjc8Et7hj;tUFa$y=r#uM8TQ#vN`jXwv6P?Tq>Z<Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L011Qu011Qvs^VjL00007bV*G`2igJ< z4K6hR#Lr3q00TiuL_t(I%k7g*Xk29!hM#liyYrjTHrT|_C^ZcYwg^#NC`8nSQWOf6 zxDf0n)=(%e#7&SYLHd(MaA6A?3oa}|Yiz}uCQaIuLNSesB_){{7cy8AB~8rFOlIz# zxj)B6j1Zxzv~=gQeE2x$J1^%5cfx+4f|}~e>cfrIjSZvIV?X^qIkk_snY{g?9Y6=w zb*JmXBiB1aRn;TEc7|KNZcsjClXcsL+ko|SM$;t*G6x0V+}M7xlSL&#=N%=%$6WIk zeO*OKm7`3U?(S|?)m85!kqAK$tm%vz4w*yPCk-21xbcRv;R9hdjZ!Pu$Ye75Z$?H& z{*${raarjhkWUCTRFy75&Z3-WvsEgU@cjVK^YJ_%-w!Aj9e`W9L@q)1Lxa7Ww$^9l zl>8}M%mu1w;5mLVf#+hZkd-(@gupK@k86c%I?pSx)oh->PWh|RlV862 z(R7EZkE-(X9|2Yn3RVy@FcV?#gC#n~4eM+enu6>Cy!B{6OCM~k5Jsm%rk9}gaoBYt z;Podg-t1fd!t?d+_@}$?YwI6dj;Wz0f>nL5&{SFGo@mIWMVoiFxs1-1Xn8o`$63hc z;b4=`$&ACkCS_tq`E5~Ydm0X$bLiSJ*Ard$z`LifdTc+u#OL2F|5_e3Df6=P2K{rIF9R zI-^fM_3Wx+7(Cy{i#vAWI_{e8(!~LudHJQrEVv=e2QXhd>3i?@moU0iKy$fO>qb6D zu&_wzx@)^!j`*CPs<@uDL?gv?y25O$ukwz+W-zLX9gU%X@0%ci5R1hLLj}3HQ-s<| zQxH>MvLjNiO5v|GmFDJV^*!&O@dPloq3rp{Eu3WxiCBziJbopaObjOy$>CHgHPqhT jKFQr6*;?R#?mmA3v&9JgE|m+V00000NkvXXu0mjfQX$2s literal 0 HcmV?d00001 diff --git a/images/table/list.png b/images/table/list.png new file mode 100644 index 0000000000000000000000000000000000000000..6ebc5e007c127cec03a86a6f0b081fb087264928 GIT binary patch literal 587 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 literal 0 HcmV?d00001 diff --git a/images/view/list.png b/images/view/list.png new file mode 100644 index 0000000000000000000000000000000000000000..1fb57d3083b4fb1a2d00c28e0bf72eb7c028ce82 GIT binary patch literal 928 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6jKx9jP7LeL$-D$|I14-?i-A-N z2s5sFlw1iEWH0gbb!ETF%_C?f^J2Zye4w7q0X`wFKq(Fm4lXV(Zf>(7fBiw$jF~)Wf0N)3M&heX65Zvzu36q*s5G z-z*RRTJNAKapBD&5eq`2=ZD75$%>zok+?J}WpQfS;{5c*1sN-nG8YwQEv_uvTv)lW zx^{C_C>mroH=v$?Adc?&w;@G zOXp9WJAe8-5L~!$;o`-Mm(E(}q!zyJLC^Y_=EzkmP!`}ODFuYW-B|M&m@fB*mg2aF96 zUL@3Z2^de@B|(0{4C3PAo?hNQzD@rezO~-~3Nt2oySq%N;OgT6vi&_>978H@gy zHDR~S=dChl%lg}TO3Ov9{xNUj%!Vg|p&Rr!bIQ%<3$rO-I#pMmcdqFLR>rB4ZBG|{ zmz=R-8|y^D<_`*YOQHk4Q=F4V@%Z6CMN#F zN34(d=pX&ll>VUAD5i?0{=nD@O%pd2fnCHzXhlP??F#IIckgoV^~_bv-7H0jiRWhK zp84jSZ_b>VGskwfHM#5|I{;Tpb8HX&{j6Ed)c5y3RZlU5qwP>fhK82$Sb`X*NS!I0orj_nz;PThzt2M8HB1bh zNAo@xR}gsc8XYq2XX=vzrmG&~sy9b4G4V4zp7ks++_*6VuXh888iJs2+{B2Xsw&dy zG*c10J&ehLGpMMuK~^}3yhIld$X|Ehm(&dA9_+wqdIW($5UEt^FP~uOre0ZjmyYSg zg@O#X+e`NukX0Vz-+YAo8#p55Ac*teD2S_Hskm14Ebc7Z1ZXPqd5Iz>ACiA`3K)!w ziB2p@dE|0AJryRCgkQ(LM>t`|qCn{(qs)XAS7yUl7dwbtHcMMpb?4KYI&nB0 z0&7fu>^q67Z6@Sp9#+qSj-|eJ!0(vC7SAAT^pF-ny5wgXB!3&G1-rGebzFN8^yAqcxseWwSBxB&5h{{Kf z!yljDH10UbVnJ|5^sz3L=SfU3H?y5r2qf` literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6e7efd9 --- /dev/null +++ b/main.cpp @@ -0,0 +1,10 @@ +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..30e265c --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,498 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "tableform.h" +#include "registerdialog.h" +#include "sqlform.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + QCoreApplication::setOrganizationName("Saturn Laboratories"); + QCoreApplication::setOrganizationDomain("saturnlaboratories.co.za"); + QCoreApplication::setApplicationName("IoSQL"); + ui->setupUi(this); + QList children = ui->MdiArea->findChildren(); + Q_FOREACH (QTabBar* tab, children) + { + if (!tab->tabsClosable()) + { + tab->setTabsClosable(true); + connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + } + } + m_WindowMapper = new QSignalMapper(this); + m_RegisterDialog = new RegisterDialog(this); + m_QueryForm = new SqlForm(this); + m_QueryForm->hide(); + connect(m_WindowMapper, SIGNAL(mapped(QWidget *)), + this, SLOT(setActiveSubWindow(QWidget *))); + QSettings settings; + QStringList connectionList = settings.value("connectionList").toStringList(); + for (int i = 0; i < connectionList.count(); i++) + { + QMap connectionMap = settings.value("connection " + connectionList.at(i)).toMap(); + loadConnection( + connectionMap.value("connectionName").toString(), + connectionMap.value("serverType").toString(), + connectionMap.value("serverName").toString(), + connectionMap.value("serverPort").toInt(), + connectionMap.value("databaseName").toString(), + connectionMap.value("username").toString(), + connectionMap.value("password").toString() + ); + } + QMdiArea::ViewMode viewMode = QMdiArea::ViewMode(settings.value("window mode", QVariant(QMdiArea::SubWindowView)).toInt()); + QTabWidget::TabPosition tabPosition = QTabWidget::TabPosition(settings.value("tab position", QVariant(QTabWidget::North)).toInt()); + ui->MdiArea->setViewMode(viewMode); + ui->MdiArea->setTabPosition(tabPosition); + if (viewMode == QMdiArea::SubWindowView) + { + ui->ModeSubWindowsAction->setChecked(true); + ui->ModeTabbedAction->setChecked(false); + ui->TabLocationMenu->setEnabled(false); + } + else + { + ui->ModeSubWindowsAction->setChecked(false); + ui->ModeTabbedAction->setChecked(true); + ui->TabLocationMenu->setEnabled(true); + } + if (tabPosition == QTabWidget::North) + { + ui->TabLocationNorthAction->setChecked(true); + ui->TabLocationSouthAction->setChecked(false); + ui->TabLocationEastAction->setChecked(false); + ui->TabLocationWestAction->setChecked(false); + } + else if (tabPosition == QTabWidget::South) + { + ui->TabLocationNorthAction->setChecked(false); + ui->TabLocationSouthAction->setChecked(true); + ui->TabLocationEastAction->setChecked(false); + ui->TabLocationWestAction->setChecked(false); + } + else if (tabPosition == QTabWidget::East) + { + ui->TabLocationNorthAction->setChecked(false); + ui->TabLocationSouthAction->setChecked(false); + ui->TabLocationEastAction->setChecked(true); + ui->TabLocationWestAction->setChecked(false); + } + else if (tabPosition == QTabWidget::West) + { + ui->TabLocationNorthAction->setChecked(false); + ui->TabLocationSouthAction->setChecked(false); + ui->TabLocationEastAction->setChecked(true); + ui->TabLocationWestAction->setChecked(false); + } +} + +MainWindow::~MainWindow() +{ + delete m_QueryForm; + delete m_WindowMapper; + delete m_RegisterDialog; + delete ui; +} + +void MainWindow::loadConnection(QString connectionName, QString serverType, QString serverName, int serverPort, QString databaseName, QString username, QString password) +{ + QSqlDatabase db = QSqlDatabase::addDatabase(serverType, connectionName); + db.setHostName(serverName); + db.setPort(serverPort); + db.setDatabaseName(databaseName); + db.setUserName(username); + db.setPassword(password); + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(connectionName)); + item->setIcon(0, QIcon(":/Server/images/server-database-register.png")); + ui->DatabaseTreeWidget->addTopLevelItem(item); + QSettings settings; + if (!settings.contains("connection " + connectionName)) + { + QMap connectionMap; + connectionMap.insert("connectionName", connectionName); + connectionMap.insert("serverType", serverType); + connectionMap.insert("serverName", serverName); + connectionMap.insert("serverPort", serverPort); + connectionMap.insert("databaseName", databaseName); + connectionMap.insert("username", username); + connectionMap.insert("password", password); + settings.setValue("connection " + connectionName, connectionMap); + QStringList connectionList; + if (settings.contains("connectionList")) + { + connectionList = settings.value("connectionList").toStringList(); + } + connectionList.append(connectionName); + settings.setValue("connectionList", connectionList); + } +} + +bool MainWindow::setupConnection(QString connectionName, QString serverType, QString serverName, int serverPort, QString databaseName, QString username, QString password) +{ + QSqlDatabase db = QSqlDatabase::addDatabase(serverType, connectionName); + db.setHostName(serverName); + db.setPort(serverPort); + db.setDatabaseName(databaseName); + db.setUserName(username); + db.setPassword(password); + bool ok = db.open(); + if (ok) + { + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(connectionName)); + item->setIcon(0, QIcon(":/Server/images/server-database-register.png")); + ui->DatabaseTreeWidget->addTopLevelItem(item); + QSettings settings; + if (!settings.contains("connection " + connectionName)) + { + QMap connectionMap; + connectionMap.insert("connectionName", connectionName); + connectionMap.insert("serverType", serverType); + connectionMap.insert("serverName", serverName); + connectionMap.insert("serverPort", serverPort); + connectionMap.insert("databaseName", databaseName); + connectionMap.insert("username", username); + connectionMap.insert("password", password); + settings.setValue("connection " + connectionName, connectionMap); + QStringList connectionList; + if (settings.contains("connectionList")) + { + connectionList = settings.value("connectionList").toStringList(); + } + connectionList.append(connectionName); + settings.setValue("connectionList", connectionList); + } + } + else + { + QSqlError error = QSqlDatabase::database(connectionName).lastError(); + QMessageBox::critical(this, "Error opening database", "Error occurred: " + error.text()); + } + return ok; +} + +void MainWindow::on_WindowMenu_aboutToShow() +{ + ui->WindowMenu->clear(); + ui->WindowMenu->addAction(ui->WindowCascadeAction); + ui->WindowMenu->addAction(ui->WindowTileAction); + ui->WindowMenu->addSeparator(); + QList windows = ui->MdiArea->subWindowList(); + if (!windows.isEmpty()) + { + ui->WindowMenu->addSeparator(); + for (int i = 0; i < windows.size(); ++i) + { + QMdiSubWindow *child = windows.at(i); + QString text; + if (i < 9) + { + text = tr("&%1 %2").arg(i + 1).arg(child->windowTitle()); + } + else + { + text = tr("%1").arg(child->windowTitle()); + } + QAction *action = ui->WindowMenu->addAction(text); + action->setCheckable(true); + action->setChecked(child == ui->MdiArea->activeSubWindow()); + connect(action, SIGNAL(triggered()), m_WindowMapper, SLOT(map())); + m_WindowMapper->setMapping(action, child); + } + } + } + +void MainWindow::setActiveSubWindow(QWidget *window) +{ + if (!window) + return; + ui->MdiArea->setActiveSubWindow(qobject_cast(window)); +} + +void MainWindow::changeEvent(QEvent *e) +{ + QMainWindow::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void MainWindow::on_DatabaseRegisterAction_triggered() +{ + if (m_RegisterDialog->exec()) + { + setupConnection( + m_RegisterDialog->connectionName(), + m_RegisterDialog->serverType(), + m_RegisterDialog->serverName(), + m_RegisterDialog->serverPort(), + m_RegisterDialog->database(), + m_RegisterDialog->username(), + m_RegisterDialog->password() + ); + } +} + +void MainWindow::on_DatabaseTreeWidget_doubleClicked(QModelIndex index) +{ + QTreeWidgetItem *item = ui->DatabaseTreeWidget->currentItem(); + if (item->parent() == 0 && item->childCount() == 0) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QSqlDatabase db = QSqlDatabase::database(item->text(0)); + bool ok = db.open(); + if (ok) + { + /* Get the list of tables */ + QTreeWidgetItem *tablesItem = new QTreeWidgetItem(item, QStringList("Tables")); + tablesItem->setIcon(0, QIcon(":/Table/images/table/list.png")); + item->addChild(tablesItem); + QStringList tables = db.tables(); + tables.sort(); + for (int i = 0; i < tables.count(); i++) + { + QTreeWidgetItem *table = new QTreeWidgetItem(tablesItem, QStringList(tables.at(i))); + table->setIcon(0, QIcon(":/Table/images/table/table.png")); + tablesItem->addChild(table); + } + /* Get the list of views */ + QTreeWidgetItem *viewsItem = new QTreeWidgetItem(item, QStringList("Views")); + viewsItem->setIcon(0, QIcon(":/View/images/view/list.png")); + item->addChild(viewsItem); + QStringList views = db.tables(QSql::Views); + views.sort(); + for (int i = 0; i < views.count(); i++) + { + QTreeWidgetItem *view = new QTreeWidgetItem(viewsItem, QStringList(views.at(i))); + view->setIcon(0, QIcon(":/View/images/view/view.png")); + viewsItem->addChild(view); + } + QApplication::restoreOverrideCursor(); + } + else + { + QApplication::restoreOverrideCursor(); + QSqlError error = db.lastError(); + QMessageBox::critical(this, "Error opening database", "Error occurred: " + error.text()); + } + } + else if (item->parent() != 0 && item->childCount() == 0) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + TableForm *tableForm = new TableForm(ui->MdiArea); + tableForm->setTable(item->parent()->parent()->text(0), item->text(0)); + QString tableName = item->parent()->parent()->text(0) + "." + item->text(0); + QList windows = ui->MdiArea->subWindowList(); + bool foundWindow = false; + if (!windows.isEmpty()) + { + for (int i = 0; i < windows.size(); ++i) + { + if (windows.at(i)->windowTitle() == tableName) + { + ui->MdiArea->setActiveSubWindow(windows.at(i)); + foundWindow = true; + } + } + } + if (!foundWindow) + { + QMdiSubWindow *subWindow = ui->MdiArea->addSubWindow(tableForm); + subWindow->setWindowTitle(tableName); + subWindow->setWindowIcon(QIcon(":/Table/images/table/icon.png")); + subWindow->showMaximized(); + } + QApplication::restoreOverrideCursor(); + } +} + + +void MainWindow::on_DatabaseDeregisterAction_triggered() +{ + QTreeWidgetItem *item = ui->DatabaseTreeWidget->currentItem(); + if (item != 0 && item->parent() == 0 && item->childCount() == 0) + { + if (QMessageBox::question(this, "De-register Database", "Are you sure you want to de-register \"" + item->text(0) + "\"?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + { + QString connectionName = item->text(0); + QSettings settings; + if (settings.contains("connection " + connectionName)) + { + settings.remove("connection " + connectionName); + QStringList connectionList; + if (settings.contains("connectionList")) + { + connectionList = settings.value("connectionList").toStringList(); + } + connectionList.removeAt(connectionList.indexOf(connectionName)); + settings.setValue("connectionList", connectionList); + } + delete item; + } + } +} + +void MainWindow::on_HelpAboutQtAction_triggered() +{ + QMessageBox::aboutQt(this); +} + +void MainWindow::on_HelpAboutAction_triggered() +{ + QMessageBox::about(this, "About IoSQL", "

About IoSQL

" + "

IoSQL is a light-weight database-independent data explorer.

" + "

Copyright © 2010 Saturn Laboratories.

" + "

This program is free software: you can redistribute it and/or modify it " + "under the terms of the GNU General Public License as published by the Free " + "Software Foundation, either version 3 of the License, or (at your option) " + "any later version.

" + "

This program is distributed in the hope that it will be useful, " + "but WITHOUT ANY WARRANTY; without even the implied warranty of " + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + "GNU General Public License for more details.

" + "

You should have received a copy of the GNU General Public License " + "along with this program. If not, see " + "http://www.gnu.org/licenses/

"); +} + +void MainWindow::on_ModeSubWindowsAction_triggered() +{ + ui->MdiArea->setViewMode(QMdiArea::SubWindowView); + QSettings settings; + settings.setValue("window mode", QVariant(QMdiArea::SubWindowView)); + ui->ModeSubWindowsAction->setChecked(true); + ui->ModeTabbedAction->setChecked(false); + ui->TabLocationMenu->setEnabled(false); +} + +void MainWindow::on_ModeTabbedAction_triggered() +{ + ui->MdiArea->setViewMode(QMdiArea::TabbedView); + ui->MdiArea->setDocumentMode(true); + QSettings settings; + settings.setValue("window mode", QVariant(QMdiArea::TabbedView)); + ui->ModeSubWindowsAction->setChecked(false); + ui->ModeTabbedAction->setChecked(true); + ui->TabLocationMenu->setEnabled(true); +} + +void MainWindow::on_TabLocationNorthAction_triggered() +{ + ui->MdiArea->setTabPosition(QTabWidget::North); + QSettings settings; + settings.setValue("tab position", QVariant(QTabWidget::North)); + ui->TabLocationNorthAction->setChecked(true); + ui->TabLocationSouthAction->setChecked(false); + ui->TabLocationEastAction->setChecked(false); + ui->TabLocationWestAction->setChecked(false); +} + +void MainWindow::on_TabLocationSouthAction_triggered() +{ + ui->MdiArea->setTabPosition(QTabWidget::South); + QSettings settings; + settings.setValue("tab position", QVariant(QTabWidget::South)); + ui->TabLocationNorthAction->setChecked(false); + ui->TabLocationSouthAction->setChecked(true); + ui->TabLocationEastAction->setChecked(false); + ui->TabLocationWestAction->setChecked(false); +} + +void MainWindow::on_TabLocationEastAction_triggered() +{ + ui->MdiArea->setTabPosition(QTabWidget::East); + QSettings settings; + settings.setValue("tab position", QVariant(QTabWidget::East)); + ui->TabLocationNorthAction->setChecked(false); + ui->TabLocationSouthAction->setChecked(false); + ui->TabLocationEastAction->setChecked(true); + ui->TabLocationWestAction->setChecked(false); +} + +void MainWindow::on_TabLocationWestAction_triggered() +{ + ui->MdiArea->setTabPosition(QTabWidget::West); + QSettings settings; + settings.setValue("tab position", QVariant(QTabWidget::West)); + ui->TabLocationNorthAction->setChecked(false); + ui->TabLocationSouthAction->setChecked(false); + ui->TabLocationEastAction->setChecked(false); + ui->TabLocationWestAction->setChecked(true); +} + +void MainWindow::on_DatabaseEditAction_triggered() +{ + QTreeWidgetItem *item = ui->DatabaseTreeWidget->currentItem(); + if (item != 0 && item->parent() == 0 && item->childCount() == 0) + { + QString oldConnectionName = item->text(0); + QSettings settings; + QMap connectionMap = settings.value("connection " + oldConnectionName).toMap(); + m_RegisterDialog->setConnectionName(oldConnectionName); + m_RegisterDialog->setServerType(connectionMap.value("serverType", QVariant("")).toString()); + m_RegisterDialog->setServerName(connectionMap.value("serverName", QVariant("")).toString()); + m_RegisterDialog->setServerPort(connectionMap.value("serverPort", QVariant(0)).toInt()); + m_RegisterDialog->setDatabase(connectionMap.value("databaseName", QVariant("")).toString()); + m_RegisterDialog->setUsername(connectionMap.value("username", QVariant("")).toString()); + m_RegisterDialog->setPassword(connectionMap.value("password", QVariant("")).toString()); + if (m_RegisterDialog->exec()) + { + QString connectionName = m_RegisterDialog->connectionName(); + QString serverType = m_RegisterDialog->serverType(); + QString serverName = m_RegisterDialog->serverName(); + int serverPort = m_RegisterDialog->serverPort(); + QString database = m_RegisterDialog->database(); + QString username = m_RegisterDialog->username(); + QString password = m_RegisterDialog->password(); + QSqlDatabase db = QSqlDatabase::database(connectionName); + if (connectionName != oldConnectionName || serverType != db.driverName()) + { + QSqlDatabase::removeDatabase(oldConnectionName); + db = QSqlDatabase::addDatabase(serverType, connectionName); + } + db.setHostName(serverName); + db.setPort(serverPort); + db.setDatabaseName(database); + db.setUserName(username); + db.setPassword(password); + connectionMap.insert("connectionName", connectionName); + connectionMap.insert("serverType", serverType); + connectionMap.insert("serverName", serverName); + connectionMap.insert("serverPort", serverPort); + connectionMap.insert("databaseName", database); + connectionMap.insert("username", username); + connectionMap.insert("password", password); + settings.remove("connection " + oldConnectionName); + settings.setValue("connection " + connectionName, connectionMap); + item->setText(0, connectionName); + } + } +} + +void MainWindow::on_DatabaseRunQueryAction_triggered() +{ + m_QueryForm->show(); +} + +void MainWindow::closeTab(int i) +{ + QMdiSubWindow *sub = ui->MdiArea->subWindowList()[i]; + QWidget *win = sub->widget(); + win->close(); + ui->MdiArea->setActiveSubWindow(sub); + ui->MdiArea->closeActiveSubWindow(); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..e5520d7 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,50 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include "registerdialog.h" +#include "sqlform.h" + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); +void loadConnection(QString connectionName, QString serverType, QString serverName, int serverPort, QString databaseName, QString username, QString password); +bool setupConnection(QString connectionName, QString serverType, QString serverName, int serverPort, QString databaseName, QString username, QString password); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::MainWindow *ui; + QSignalMapper *m_WindowMapper; + RegisterDialog *m_RegisterDialog; + SqlForm *m_QueryForm; + +private slots: + void setActiveSubWindow(QWidget *window); + void closeTab(int i); + void on_DatabaseRunQueryAction_triggered(); + void on_DatabaseEditAction_triggered(); + void on_TabLocationWestAction_triggered(); + void on_TabLocationEastAction_triggered(); + void on_TabLocationSouthAction_triggered(); + void on_TabLocationNorthAction_triggered(); + void on_ModeTabbedAction_triggered(); + void on_ModeSubWindowsAction_triggered(); + void on_HelpAboutAction_triggered(); + void on_HelpAboutQtAction_triggered(); + void on_DatabaseDeregisterAction_triggered(); + void on_DatabaseTreeWidget_doubleClicked(QModelIndex index); + void on_DatabaseRegisterAction_triggered(); + void on_WindowMenu_aboutToShow(); +}; + +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..4df7da1 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,339 @@ + + + MainWindow + + + + 0 + 0 + 600 + 400 + + + + IoSQL Database Manager + + + + :/Server/images/server-database-register.png:/Server/images/server-database-register.png + + + + + 0 + + + 0 + + + + + QMdiArea::TabbedView + + + + + + + + + 0 + 0 + 600 + 21 + + + + + &Database + + + + + + + + + + + + &Window + + + + + + + &Help + + + + + + + &View + + + + Tab &Location + + + + + + + + + + + + + + + + + + + TopToolBarArea + + + false + + + + + + + + + false + + + QDockWidget::AllDockWidgetFeatures + + + Databases + + + 1 + + + + + 0 + + + 0 + + + + + + 22 + 22 + + + + true + + + true + + + true + + + + 1 + + + + + + + + + + + :/Server/images/server-database-register.png:/Server/images/server-database-register.png + + + &Register + + + Register a database + + + + + &Cascade + + + Cascade all the windows + + + + + Tile + + + Tile all the windows + + + + + + :/Server/images/server-database-deregister.png:/Server/images/server-database-deregister.png + + + De-register + + + De-register database + + + + + &About + + + About IoSQL + + + + + &About Qt + + + + + true + + + &Tabbed + + + Set the window mode to tabs + + + + + true + + + &Sub-Windows + + + Set the window mode to Sub-Windows + + + + + true + + + &North + + + Show tabs on the top + + + + + true + + + &South + + + Show tabs on the bottom + + + + + true + + + &East + + + Show the tabs on the right + + + + + true + + + &West + + + Show the tabs on the left + + + + + + :/Server/images/server-database-edit.png:/Server/images/server-database-edit.png + + + &Edit Registration + + + Edit database registration details + + + + + + :/Table/images/run-build.png:/Table/images/run-build.png + + + Run &Query + + + + + E&xit + + + + + + + + + + WindowCascadeAction + triggered() + MdiArea + cascadeSubWindows() + + + -1 + -1 + + + 432 + 216 + + + + + WindowTileAction + triggered() + MdiArea + tileSubWindows() + + + -1 + -1 + + + 432 + 216 + + + + + diff --git a/registerdialog.cpp b/registerdialog.cpp new file mode 100644 index 0000000..a982dba --- /dev/null +++ b/registerdialog.cpp @@ -0,0 +1,125 @@ +#include "registerdialog.h" +#include "ui_registerdialog.h" + +RegisterDialog::RegisterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::RegisterDialog) +{ + ui->setupUi(this); + QValidator *validator = new QIntValidator(0, 999999, this); + ui->PortLineEdit->setValidator(validator); +} + +RegisterDialog::~RegisterDialog() +{ + delete ui; +} + +void RegisterDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +QString RegisterDialog::connectionName() +{ + return ui->ConnectionLineEdit->text(); +} + +void RegisterDialog::setConnectionName(const QString connectionName) +{ + ui->ConnectionLineEdit->setText(connectionName); +} + +QString RegisterDialog::serverType() +{ + QString typeName = ui->TypeComboBox->currentText(); + if (typeName == "PostgreSQL") + { + return "QPSQL"; + } + else if (typeName == "MySQL") + { + return "QMYSQL"; + } + else if (typeName == "SQLite") + { + return "QSQLITE"; + } + return ""; +} + +void RegisterDialog::setServerType(const QString serverType) +{ + int typeIndex = 0; + if (serverType == "QPSQL") + { + typeIndex = ui->TypeComboBox->findText("PostgreSQL"); + } + else if (serverType == "QMYSQL") + { + typeIndex = ui->TypeComboBox->findText("MySQL"); + } + else if (serverType == "QSQLITE") + { + typeIndex = ui->TypeComboBox->findText("SQLite"); + } + ui->TypeComboBox->setCurrentIndex(typeIndex); +} + +QString RegisterDialog::serverName() +{ + return ui->ServerLineEdit->text(); +} + +void RegisterDialog::setServerName(const QString serverName) +{ + ui->ServerLineEdit->setText(serverName); +} + +int RegisterDialog::serverPort() +{ + QString port = ui->PortLineEdit->text(); + return port.toInt(); +} + +void RegisterDialog::setServerPort(const int port) +{ + ui->PortLineEdit->setText(QString::number(port)); +} + +QString RegisterDialog::database() +{ + return ui->DatabaseLineEdit->text(); +} + +void RegisterDialog::setDatabase(const QString database) +{ + ui->DatabaseLineEdit->setText(database); +} + +QString RegisterDialog::username() +{ + return ui->UsernameLineEdit->text(); +} + +void RegisterDialog::setUsername(const QString username) +{ + ui->UsernameLineEdit->setText(username); +} + +QString RegisterDialog::password() +{ + return ui->PasswordLineEdit->text(); +} + +void RegisterDialog::setPassword(const QString password) +{ + ui->PasswordLineEdit->setText(password); +} diff --git a/registerdialog.h b/registerdialog.h new file mode 100644 index 0000000..58fd9fb --- /dev/null +++ b/registerdialog.h @@ -0,0 +1,39 @@ +#ifndef REGISTERDIALOG_H +#define REGISTERDIALOG_H + +#include + +namespace Ui { + class RegisterDialog; +} + +class RegisterDialog : public QDialog { + Q_OBJECT +public: + RegisterDialog(QWidget *parent = 0); + ~RegisterDialog(); + QString connectionName(); + void setConnectionName(const QString connectionName); + QString serverType(); + void setServerType(const QString serverType); + QString serverName(); + void setServerName(const QString serverName); + int serverPort(); + void setServerPort(const int port); + QString database(); + void setDatabase(const QString database); + QString username(); + void setUsername(const QString username); + QString password(); + void setPassword(const QString password); + +protected: + void changeEvent(QEvent *e); + +private slots: + +private: + Ui::RegisterDialog *ui; +}; + +#endif // REGISTERDIALOG_H diff --git a/registerdialog.ui b/registerdialog.ui new file mode 100644 index 0000000..7b5f06f --- /dev/null +++ b/registerdialog.ui @@ -0,0 +1,199 @@ + + + RegisterDialog + + + + 0 + 0 + 361 + 281 + + + + Dialog + + + + 8 + + + 8 + + + + + Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + 8 + + + 8 + + + + + Connection Name: + + + + + + + + + + Server Address: + + + + + + + + + + Server Port: + + + + + + + true + + + + + + + + 0 + 0 + + + + + PostgreSQL + + + + + MySQL + + + + + SQLite + + + + + + + + Server Type: + + + + + + + Database: + + + + + + + + + + Username: + + + + + + + + + + Password: + + + + + + + + + + QLineEdit::Password + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + ConnectionLineEdit + TypeComboBox + ServerLineEdit + PortLineEdit + DatabaseLineEdit + UsernameLineEdit + PasswordLineEdit + SubmitButtonBox + + + + + SubmitButtonBox + accepted() + RegisterDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + SubmitButtonBox + rejected() + RegisterDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sqlform.cpp b/sqlform.cpp new file mode 100644 index 0000000..c400cf9 --- /dev/null +++ b/sqlform.cpp @@ -0,0 +1,38 @@ +#include "sqlform.h" +#include "ui_sqlform.h" +#include + +SqlForm::SqlForm(QWidget *parent) : + QDialog(parent), + ui(new Ui::SqlForm) +{ + QsciLexerSQL *lexer = new QsciLexerSQL(); + lexer->setDefaultPaper(QColor(255, 255, 255)); + lexer->setDefaultColor(QColor(0, 0, 0)); + lexer->setDefaultFont(QFont("monospace")); + for (int i = -1; i < 23; i++) + { + lexer->setPaper(QColor(255, 255, 255), i); + //lexer->setDefaultColor(QColor(0, 0, 0)); + lexer->setFont(QFont("monospace"), i); + } + ui->setupUi(this); + ui->QueryTextEdit->setLexer(lexer); +} + +SqlForm::~SqlForm() +{ + delete ui; +} + +void SqlForm::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/sqlform.h b/sqlform.h new file mode 100644 index 0000000..2db42bb --- /dev/null +++ b/sqlform.h @@ -0,0 +1,24 @@ +#ifndef SQLFORM_H +#define SQLFORM_H + +#include +#include + +namespace Ui { + class SqlForm; +} + +class SqlForm : public QDialog { + Q_OBJECT +public: + SqlForm(QWidget *parent = 0); + ~SqlForm(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::SqlForm *ui; +}; + +#endif // SQLFORM_H diff --git a/sqlform.ui b/sqlform.ui new file mode 100644 index 0000000..b39c10d --- /dev/null +++ b/sqlform.ui @@ -0,0 +1,50 @@ + + + SqlForm + + + + 0 + 0 + 530 + 430 + + + + Form + + + + 0 + + + 0 + + + + + Qt::Vertical + + + + + + + + + + + + + + + + + QsciScintilla + QFrame +
Qsci/qsciscintilla.h
+
+
+ + +
diff --git a/tableform.cpp b/tableform.cpp new file mode 100644 index 0000000..21c3464 --- /dev/null +++ b/tableform.cpp @@ -0,0 +1,158 @@ +#include "tableform.h" +#include "ui_tableform.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +TableForm::TableForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::TableForm) +{ + QsciLexerSQL *lexer = new QsciLexerSQL(); + lexer->setDefaultPaper(QColor(255, 255, 255)); + lexer->setDefaultColor(QColor(0, 0, 0)); + lexer->setDefaultFont(QFont("monospace")); + for (int i = -1; i < 23; i++) + { + lexer->setPaper(QColor(255, 255, 255), i); + //lexer->setDefaultColor(QColor(0, 0, 0)); + lexer->setFont(QFont("monospace"), i); + } + ui->setupUi(this); + ui->QueryTextEdit->setLexer(lexer); + m_QueryModel = 0; +} + +TableForm::~TableForm() +{ + delete m_QueryModel; + delete m_DataModel; + delete ui; +} + +void TableForm::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void TableForm::setTable(const QString connectionName, const QString tableName) +{ + QMainWindow * mainWindow = qobject_cast(window()); + if (mainWindow) + mainWindow->statusBar()->showMessage("Opening table \"" + tableName + "\"..."); + QCoreApplication::processEvents(); + m_ConnectionName = connectionName; + m_TableName = tableName; + m_Database = QSqlDatabase::database(m_ConnectionName); + m_DataModel = new QSqlTableModel(this, m_Database); + m_DataModel->setTable(m_TableName); + m_DataModel->select(); + ui->DataTableView->setModel(m_DataModel); + ui->DataTableView->resizeColumnsToContents(); + QSqlRecord record = m_DataModel->record(); + ui->StructureTableWidget->setRowCount(record.count()); + for (int i = 0; i < record.count(); i++) + { + QSqlField field = record.field(i); + QTableWidgetItem *nameItem = new QTableWidgetItem(field.name()); + QString typeName; + switch (field.type()) + { + case QVariant::String: typeName = "varchar"; break; + case QVariant::Int: typeName = "integer"; break; + case QVariant::Date: typeName = "date"; break; + case QVariant::DateTime: typeName = "datetime"; break; + case QVariant::Bool: typeName = "boolean"; break; + case QVariant::ByteArray: typeName = "byte array"; break; + case QVariant::LongLong: typeName = "bigint"; break; + default: typeName = "unknown"; break; + } + QTableWidgetItem *typeItem = new QTableWidgetItem(typeName); + QTableWidgetItem *sizeItem; + if (field.length() >= 0) + { + sizeItem = new QTableWidgetItem(field.length()); + } + else if (field.precision() >= 0) + { + sizeItem = new QTableWidgetItem(field.precision()); + } + else + { + sizeItem = new QTableWidgetItem(""); + } + QTableWidgetItem *nullItem; + if (field.requiredStatus()) + { + nullItem = new QTableWidgetItem("not null"); + } + else + { + nullItem = new QTableWidgetItem("nullable"); + } + ui->StructureTableWidget->setItem(i, 0, nameItem); + ui->StructureTableWidget->setItem(i, 1, typeItem); + ui->StructureTableWidget->setItem(i, 2, sizeItem); + ui->StructureTableWidget->setItem(i, 3, nullItem); + } + ui->StructureTableWidget->resizeColumnsToContents(); + if (mainWindow) + mainWindow->statusBar()->clearMessage(); +} + +void TableForm::on_DataCommitAction_triggered() +{ + if (m_DataModel) + { + m_DataModel->database().commit(); + } + ui->DataCommitAction->setEnabled(false); + ui->DataRollbackAction->setEnabled(false); +} + +void TableForm::on_DataRefreshAction_triggered() +{ + m_DataModel->select(); + ui->DataTableView->resizeColumnsToContents(); +} + +void TableForm::on_QueryRunAction_triggered() +{ + QMainWindow * mainWindow = qobject_cast(window()); + if (mainWindow) + mainWindow->statusBar()->showMessage("Running query..."); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QCoreApplication::processEvents(); + QString query = ""; + if (m_QueryModel == 0) + { + m_QueryModel = new QSqlQueryModel; + } + if (ui->QueryTextEdit->hasSelectedText()) + { + query = ui->QueryTextEdit->selectedText(); + } + else + { + query = ui->QueryTextEdit->text(); + } + m_QueryModel->setQuery(query, m_Database); + ui->ResultsTableView->setModel(m_QueryModel); + ui->ResultsTableView->resizeColumnsToContents(); + QApplication::restoreOverrideCursor(); + if (mainWindow) + mainWindow->statusBar()->clearMessage(); +} diff --git a/tableform.h b/tableform.h new file mode 100644 index 0000000..06a4c33 --- /dev/null +++ b/tableform.h @@ -0,0 +1,35 @@ +#ifndef TABLEFORM_H +#define TABLEFORM_H + +#include +#include + +namespace Ui { + class TableForm; +} + +class TableForm : public QWidget { + Q_OBJECT +public: + TableForm(QWidget *parent = 0); + ~TableForm(); + void setTable(const QString connectionName, const QString tableName); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::TableForm *ui; + QSqlDatabase m_Database; + QSqlTableModel *m_DataModel; + QSqlQueryModel *m_QueryModel; + QString m_ConnectionName; + QString m_TableName; + +private slots: + void on_QueryRunAction_triggered(); + void on_DataRefreshAction_triggered(); + void on_DataCommitAction_triggered(); +}; + +#endif // TABLEFORM_H diff --git a/tableform.ui b/tableform.ui new file mode 100644 index 0000000..3df074d --- /dev/null +++ b/tableform.ui @@ -0,0 +1,330 @@ + + + TableForm + + + + 0 + 0 + 638 + 440 + + + + Form + + + + :/Table/images/table/table.png:/Table/images/table/table.png + + + + 0 + + + 0 + + + + + 0 + + + + Data + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 22 + 22 + + + + + + + + + + + + + + + true + + + false + + + 20 + + + 18 + + + + + + + + Structure + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 0 + 0 + + + + + + + + + false + + + 20 + + + + Column + + + + + Type + + + + + Size + + + + + Not Null + + + + + + + + + Query + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 0 + 0 + + + + + + + + + Qt::Vertical + + + + + + + + + + + + false + + + 20 + + + + + + + + + + + + + :/Table/images/table/insert-row.png:/Table/images/table/insert-row.png + + + New Record + + + + + + :/Table/images/table/insert-column.png:/Table/images/table/insert-column.png + + + New Column + + + Add a new column + + + + + + :/Table/images/table/delete-row.png:/Table/images/table/delete-row.png + + + Remove Record + + + + + + :/Table/images/table/delete-column.png:/Table/images/table/delete-column.png + + + Remove Column + + + + + false + + + + :/Table/images/table/commit.png:/Table/images/table/commit.png + + + Commit + + + + + false + + + + :/Table/images/table/rollback.png:/Table/images/table/rollback.png + + + Rollback + + + + + + :/General/images/general/refresh.png:/General/images/general/refresh.png + + + Refresh + + + + + + :/Table/images/run-build.png:/Table/images/run-build.png + + + Run Query + + + Run an SQL query + + + F5 + + + + + + QsciScintilla + QFrame +
Qsci/qsciscintilla.h
+
+
+ + TableTabWidget + DataTableView + StructureTableWidget + QueryTextEdit + ResultsTableView + + + + + +