# # add_dir "" # # add_dir "src" # # add_dir "src/model" # # add_dir "src/view" # # add_file "COPYING" # content [0b184ad51ba2a79e85d2288d5fcf8a1ea0481ea4] # # add_file "Makefile" # content [9875d8cd59cb362a8d760c1cc41083999f14b82c] # # add_file "README" # content [e3ee753bf710a48a79ab70cbac90375066211772] # # add_file "guitone.prj" # content [b0e7906ca40ca348c0611e47b130b10acc166e58] # # add_file "guitone.pro" # content [d78a6c873a82435a4c41bc9d88bc28896f2df585] # # add_file "src/main.cpp" # content [eee44529b4f7743d19632cae782900c6d0732aa0] # # add_file "src/model/Monotone.cpp" # content [b1c6f28fd2f403ddc59ddeadffecf5753ef5ab4e] # # add_file "src/model/Monotone.h" # content [4436df110a3cbfb19a8fe6fe17c26ea3c8427322] # # add_file "src/model/Sandbox.cpp" # content [9051e6a359397bd52eee444d1766fbfec7bc5e13] # # add_file "src/model/Sandbox.h" # content [2fa4560f46a1b5c53b98d6b692c30e21d6b57038] # # add_file "src/model/SandboxItem.cpp" # content [e1ec37af3dacfee226873b073e821eb7f97dda31] # # add_file "src/model/SandboxItem.h" # content [0d83255b2e9230265e3116885ed5a00472d6be66] # # add_file "src/view/Guitone.cpp" # content [e49de344f86a9c3659cfe95c500ff56de25bb963] # # add_file "src/view/Guitone.h" # content [f62cbb2e21c3b240b5be48d82a46857b1b0a7d46] # # add_file "src/view/SandboxView.cpp" # content [0647821445e080eef89ea30b32af0c1bb002a5cb] # # add_file "src/view/SandboxView.h" # content [8a8e472c2cb938549555ef491d2a2fba4dffa0b0] # # add_file "src/view/XPM.cpp" # content [bf962ec2b218bf801f547beb213f81dede137b5a] # # add_file "src/view/XPM.h" # content [aaae6f7ed1c6e4ef7cd8a2057b922f8cd9d97ecf] --- COPYING +++ COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. --- Makefile +++ Makefile @@ -0,0 +1,218 @@ +############################################################################# +# Makefile for building: guitone +# Generated by qmake (1.07a) (Qt 3.3.4) on: Sun Mar 5 03:28:56 2006 +# Project: guitone.pro +# Template: app +# Command: $(QMAKE) -o Makefile guitone.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +LEX = flex +YACC = yacc +CFLAGS = -pipe -Wall -W -O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -m32 -march=i386 -mtune=pentium4 -fasynchronous-unwind-tables -DQT_NO_DEBUG -DQT_SHARED -DQT_THREAD_SUPPORT +CXXFLAGS = -pipe -Wall -W -O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -m32 -march=i386 -mtune=pentium4 -fasynchronous-unwind-tables -DQT_NO_DEBUG -DQT_SHARED -DQT_THREAD_SUPPORT +LEXFLAGS = +YACCFLAGS= -d +INCPATH = -I/usr/lib/qt-3.3/mkspecs/default -I. -I. -Isrc -I$(QTDIR)/include +LINK = g++ +LFLAGS = +LIBS = $(SUBLIBS) -L$(QTDIR)/lib -L/usr/X11R6/lib -lqt-mt -lXext -lX11 -lm +AR = ar cqs +RANLIB = +MOC = $(QTDIR)/bin/moc +UIC = $(QTDIR)/bin/uic +QMAKE = qmake +TAR = tar -cf +GZIP = gzip -9f +COPY = cp -f +COPY_FILE= $(COPY) +COPY_DIR = $(COPY) -r +INSTALL_FILE= $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) +DEL_FILE = rm -f +SYMLINK = ln -sf +DEL_DIR = rmdir +MOVE = mv -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files + +HEADERS = src/view/XPM.h \ + src/view/Guitone.h \ + src/view/SandboxView.h \ + src/model/Monotone.h \ + src/model/Sandbox.h \ + src/model/SandboxItem.h +SOURCES = src/view/XPM.cpp \ + src/view/Guitone.cpp \ + src/view/SandboxView.cpp \ + src/model/Monotone.cpp \ + src/model/Sandbox.cpp \ + src/model/SandboxItem.cpp \ + src/main.cpp +OBJECTS = XPM.o \ + Guitone.o \ + SandboxView.o \ + Monotone.o \ + Sandbox.o \ + SandboxItem.o \ + main.o +FORMS = +UICDECLS = +UICIMPLS = +SRCMOC = src/view/moc_Guitone.cpp \ + src/view/moc_SandboxView.cpp \ + src/model/moc_Monotone.cpp \ + src/model/moc_Sandbox.cpp +OBJMOC = moc_Guitone.o \ + moc_SandboxView.o \ + moc_Monotone.o \ + moc_Sandbox.o +DIST = guitone.pro +QMAKE_TARGET = guitone +DESTDIR = +TARGET = guitone + +first: all +####### Implicit rules + +.SUFFIXES: .c .o .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): $(UICDECLS) $(OBJECTS) $(OBJMOC) + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS) + +mocables: $(SRCMOC) +uicables: $(UICDECLS) $(UICIMPLS) + +$(MOC): + ( cd $(QTDIR)/src/moc && $(MAKE) ) + +Makefile: guitone.pro /usr/lib/qt-3.3/mkspecs/default/qmake.conf /usr/lib/qt-3.3/lib/libqt-mt.prl + $(QMAKE) -o Makefile guitone.pro +qmake: + @$(QMAKE) -o Makefile guitone.pro + +dist: + @mkdir -p .tmp/guitone && $(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) .tmp/guitone/ && ( cd `dirname .tmp/guitone` && $(TAR) guitone.tar guitone && $(GZIP) guitone.tar ) && $(MOVE) `dirname .tmp/guitone`/guitone.tar.gz . && $(DEL_FILE) -r .tmp/guitone + +mocclean: + -$(DEL_FILE) $(OBJMOC) + -$(DEL_FILE) $(SRCMOC) + +uiclean: + +yaccclean: +lexclean: +clean: mocclean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) $(TARGET) $(TARGET) + + +FORCE: + +####### Compile + +XPM.o: src/view/XPM.cpp src/view/XPM.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o XPM.o src/view/XPM.cpp + +Guitone.o: src/view/Guitone.cpp src/view/Guitone.h \ + src/model/Sandbox.h \ + src/view/SandboxView.h \ + src/model/SandboxItem.h \ + src/model/Monotone.h \ + src/view/XPM.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Guitone.o src/view/Guitone.cpp + +SandboxView.o: src/view/SandboxView.cpp src/view/SandboxView.h \ + src/view/XPM.h \ + src/model/SandboxItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SandboxView.o src/view/SandboxView.cpp + +Monotone.o: src/model/Monotone.cpp src/model/Monotone.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Monotone.o src/model/Monotone.cpp + +Sandbox.o: src/model/Sandbox.cpp src/model/Sandbox.h \ + src/model/SandboxItem.h \ + src/model/Monotone.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Sandbox.o src/model/Sandbox.cpp + +SandboxItem.o: src/model/SandboxItem.cpp src/model/SandboxItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SandboxItem.o src/model/SandboxItem.cpp + +main.o: src/main.cpp src/view/Guitone.h \ + src/model/Sandbox.h \ + src/view/SandboxView.h \ + src/model/SandboxItem.h \ + src/model/Monotone.h \ + src/view/XPM.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o src/main.cpp + +moc_Guitone.o: src/view/moc_Guitone.cpp src/view/Guitone.h src/model/Sandbox.h \ + src/view/SandboxView.h \ + src/model/SandboxItem.h \ + src/model/Monotone.h \ + src/view/XPM.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_Guitone.o src/view/moc_Guitone.cpp + +moc_SandboxView.o: src/view/moc_SandboxView.cpp src/view/SandboxView.h src/view/XPM.h \ + src/model/SandboxItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_SandboxView.o src/view/moc_SandboxView.cpp + +moc_Monotone.o: src/model/moc_Monotone.cpp src/model/Monotone.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_Monotone.o src/model/moc_Monotone.cpp + +moc_Sandbox.o: src/model/moc_Sandbox.cpp src/model/Sandbox.h src/model/SandboxItem.h \ + src/model/Monotone.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_Sandbox.o src/model/moc_Sandbox.cpp + +src/view/moc_Guitone.cpp: $(MOC) src/view/Guitone.h + $(MOC) src/view/Guitone.h -o src/view/moc_Guitone.cpp + +src/view/moc_SandboxView.cpp: $(MOC) src/view/SandboxView.h + $(MOC) src/view/SandboxView.h -o src/view/moc_SandboxView.cpp + +src/model/moc_Monotone.cpp: $(MOC) src/model/Monotone.h + $(MOC) src/model/Monotone.h -o src/model/moc_Monotone.cpp + +src/model/moc_Sandbox.cpp: $(MOC) src/model/Sandbox.h + $(MOC) src/model/Sandbox.h -o src/model/moc_Sandbox.cpp + +####### Install + +install: + +uninstall: + --- README +++ README @@ -0,0 +1,48 @@ + +guitone - a Qt-Frontend for monotone +==================================== + +guitone is a very basic frontend to monotone. +It currently only allows to browse through the +workspace contents just like a normal file +browser, but by displaying additional file +status information. +Context-sensitive menus allow to hide ignored +items and the navigation between renamed items. + +To build & run guitone just do + + $ cd /path/to/guitone + $ qmake guitone.pro && make && ./guitone + +You need to have monotone installed with at least +version 0.26pre3 and you need a checked out workspace. +Via CTRL-I you select the base folder of the +sandbox which is then displayed. + +Please don't bash me too hard for this little +app and the UI design, it is my first Qt +program. Contributions are alway welcome! + +TODO +==== + +* real actions on the workspace (add/drop/update/...) +* abilitiy to view the history of the branch/ a file +* session/workspace saving on restart +* cross-platform builds +* make icons for all common file/folder states +* well, anything else you can think of... + +Author +====== + +Thomas Keller +ICQ: 85945241 + +version history +=============== + +2006-03-05 (0.2) - Fixes to let it work with 0.26pre3 + +2006-03-05 (0.1) - Initial release --- guitone.prj +++ guitone.prj @@ -0,0 +1,126 @@ +# Anjuta Version 1.2.3 +Compatibility Level: 1 + + + + + + + + + + + + + + + + + + + + +props.file.type=project + +anjuta.version=1.2.3 +anjuta.compatibility.level=1 + +project.name=guitone +project.type=GENERIC +project.target.type=EXECUTABLE +project.version=0.1 +project.author=Thomas Keller +project.source.target=unknown +project.has.gettext=0 +project.gui.command= +project.programming.language=C_C++ +project.excluded.modules=intl + +project.config.extra.modules.before= +project.config.extra.modules.after= +project.config.blocked=1 +project.config.disable.overwriting=1 1 1 1 1 1 1 1 1 + +project.menu.entry=guitone Version 0.1 +project.menu.group=Application +project.menu.comment=guitone Version 0.1 +project.menu.icon= +project.menu.need.terminal=0 + +project.configure.options= +anjuta.program.arguments= +preferences.build.option.jobs=0 +preferences.build.option.silent=0 +preferences.build.option.autosave=1 +preferences.anjuta.make.options=-k +preferences.make=make +preferences.build.option.keep.going=1 +preferences.build.option.warn.undef=0 +preferences.autoformat.custom.style= -i8 -sc -bli0 -bl0 -cbi0 -ss +preferences.indent.opening=0 +preferences.autoformat.disable=1 +preferences.indent.automatic=1 +preferences.use.tabs=1 +preferences.indent.size=4 +preferences.tabsize=4 +preferences.indent.closing=0 + +module.include.name=. +module.include.type= +module.include.files=\ + src/model/Sandbox.h\ + src/model/SandboxItem.h\ + src/view/Guitone.h\ + src/view/SandboxView.h\ + src/view/XPM.h\ + src/model/Monotone.h + +module.source.name=. +module.source.type= +module.source.files=\ + src/main.cpp\ + src/model/Sandbox.cpp\ + src/model/SandboxItem.cpp\ + src/view/Guitone.cpp\ + src/view/SandboxView.cpp\ + src/model/Monotone.cpp\ + src/view/XPM.cpp + +module.pixmap.name=. +module.pixmap.type= +module.pixmap.files= + +module.data.name=. +module.data.type= +module.data.files= + +module.help.name=. +module.help.type= +module.help.files= + +module.doc.name=. +module.doc.type= +module.doc.files=\ + COPYING + +module.po.files= + +compiler.options.supports= +compiler.options.include.paths=\ + .\ + ..\ + /usr/lib/qt-3.3/include/ +compiler.options.library.paths= +compiler.options.libraries= +compiler.options.libraries.selected= +compiler.options.defines=\ + HAVE_CONFIG_H +compiler.options.defines.selected= +compiler.options.warning.buttons=0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 +compiler.options.optimize.buttons=0 0 1 0 +compiler.options.other.buttons=1 0 +compiler.options.other.c.flags= +compiler.options.other.l.flags= +compiler.options.other.l.libs= + +project.src.paths= --- guitone.pro +++ guitone.pro @@ -0,0 +1,16 @@ +HEADERS += src/view/XPM.h \ + src/view/Guitone.h \ + src/view/SandboxView.h \ + src/model/Monotone.h \ + src/model/Sandbox.h \ + src/model/SandboxItem.h +SOURCES += src/view/XPM.cpp \ + src/view/Guitone.cpp \ + src/view/SandboxView.cpp \ + src/model/Monotone.cpp \ + src/model/Sandbox.cpp \ + src/model/SandboxItem.cpp \ + src/main.cpp +TEMPLATE = app +DEPENDPATH += src +INCLUDEPATH += . src --- src/main.cpp +++ src/main.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include +#include "view/Guitone.h" + +int main( int argc, char ** argv ) { + QApplication qApp(argc,argv); + Guitone *mainWnd = new Guitone(); + mainWnd->setCaption( "guitone" ); + mainWnd->show(); + qApp.connect(&qApp, SIGNAL(lastWindowClosed()), &qApp, SLOT(quit())); + return qApp.exec(); +} --- src/model/Monotone.cpp +++ src/model/Monotone.cpp @@ -0,0 +1,116 @@ + +#include "Monotone.h" + +Monotone* Monotone::instance = 0; + +Monotone::Monotone() : QProcess() +{ + isRunning = false; + output = new QStringList(); +} + +Monotone::~Monotone() +{ + kill(); +} + +Monotone* Monotone::singleton(QDir *workingDirectory = 0) +{ + if (instance == 0) + { + instance = new Monotone(); + if (!instance->openConnection(workingDirectory)) + { + qFatal("Couldn't connect to monotone. Have you installed it properly?"); + } + } + return instance; +} + +bool Monotone::openConnection(QDir *workingDirectory) +{ + // versions before 0.26pre3 are not supported + // in that version monotone changed its binary and + // workspace folder names to mtn and _MTN + addArgument("mtn"); + addArgument("automate"); + addArgument("stdio"); + setWorkingDirectory(*workingDirectory); + + connect( + this, SIGNAL(readyReadStdout()), + this, SLOT(parseLineFromStdout()) + ); + + if (!start()) + { + return false; + } + return true; +} + +bool Monotone::triggerCommand(QString cmd) +{ + if (isRunning) + { + return false; + } + + isRunning = true; + output->clear(); + + QString finalCmd; + QStringList parts = QStringList::split(' ', cmd); + + // a command starts with a lowercase L + finalCmd += "l"; + + // and each part of the command is prefixed with its size + // separated by a colon + for (QStringList::Iterator it = parts.begin(); it != parts.end(); ++it) + { + finalCmd += QString::number((*it).length()); + finalCmd += ":"; + finalCmd += *it; + } + + // finally, the cmd ends with "e\n" + finalCmd += "e\n"; + qDebug("Final command: %s", finalCmd.latin1()); + writeToStdin(finalCmd); + return true; +} + +void Monotone::parseLineFromStdout() +{ + QByteArray byteArray; + QRegExp regex("^(\\d+):(\\d+):([ml]):(\\d+):([^\\n]*)"); + //regex.setMinimal(TRUE); + + while (byteArray = readStdout()) + { + if (regex.search(byteArray.data()) == -1) + { + qWarning("Can't parse data %s", byteArray.data()); + continue; + } + QStringList list = regex.capturedTexts(); + + // last output? then this contains just the status, + // and no additional information + if (list[3].compare("l") == 0) + { + isRunning = false; + emit commandFinished(list[2].toInt()); + break; + } + + // valid output, append it + output->append(list[5]); + } +} + +QStringList* Monotone::getOutput() +{ + return output; +} --- src/model/Monotone.h +++ src/model/Monotone.h @@ -0,0 +1,31 @@ + +#ifndef MONOTONE_H +#define MONOTONE_H + +#include +#include +#include + +class Monotone : public QProcess +{ + Q_OBJECT + public: + static Monotone* singleton(QDir*); + ~Monotone(); + bool triggerCommand(QString cmd); + QStringList* getOutput(); + protected: + Monotone(); + private: + bool openConnection(QDir*); + QStringList *output; + bool isRunning; + + static Monotone* instance; + private slots: + void parseLineFromStdout(); + signals: + void commandFinished(int returnCode); +}; + +#endif --- src/model/Sandbox.cpp +++ src/model/Sandbox.cpp @@ -0,0 +1,241 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "Sandbox.h" + +Sandbox::Sandbox() {} + +Sandbox::~Sandbox() +{ + delete monotone; + delete workspaceDir; +} + +bool Sandbox::setWorkspaceDir(QString workspace) +{ + workspaceDir = new QDir(workspace); + if (!workspaceDir->exists()) + { + qWarning("Cannot find directory " + workspace); + return false; + } + + do + { + if (workspaceDir->cd("_MTN")) + { + return true; + } + } + while (!workspaceDir->isRoot() && workspaceDir->cdUp()); + + qWarning("Cannot find _MTN directory in or above "+ workspace); + return false; +} + +bool Sandbox::readInventory() +{ + monotone = Monotone::singleton(workspaceDir); + + connect( + monotone, SIGNAL(commandFinished(int)), + this, SLOT(parseInventory(int)) + ); + + return monotone->triggerCommand("inventory"); +} + +void Sandbox::parseInventory(int returnCode) +{ + QStringList *output = monotone->getOutput(); + + if (returnCode > 0) + { + QString error = output->front(); + qWarning("A error occured: %s", error.latin1()); + return; + } + + QRegExp regex("^(R|D|[ ])(R|A|[ ])(M|P|U|I|[ ])\\s(\\d+)\\s(\\d+)\\s(.+)$"); + regex.setMinimal(TRUE); + + std::map renameMap; + std::map::iterator renameIter; + + SandboxItem *item; + std::list* tempItems = new std::list(); + + for (QStringList::Iterator it = output->begin(); it != output->end(); ++it) + { + if (regex.search(*it) == -1) + { + qWarning("Couldn't parse inventory line %s", (*it).latin1()); + continue; + } + QStringList list = regex.capturedTexts(); + int status = 0; + + // the first match + if (list[1].compare("R") == 0) + { + status |= SandboxItem::RenamedFrom; + } else + if (list[1].compare("D") == 0) + { + status |= SandboxItem::Dropped; + } + else + { + if (list[1].compare(" ") != 0) + { + qWarning("Unknown status first tripel " + list[1]); + } + } + + // the second match + if (list[2].compare("R") == 0) + { + status |= SandboxItem::RenamedTo; + } else + if (list[2].compare("A") == 0) + { + status |= SandboxItem::Added; + } + else + { + if (list[2].compare(" ") != 0) + { + qWarning("Unknown status second tripel " + list[2]); + } + } + + // the third match + if (list[3].compare("M") == 0) + { + status |= SandboxItem::Missing; + } else + if (list[3].compare("P") == 0) + { + status |= SandboxItem::Patched; + } else + if (list[3].compare("U") == 0) + { + status |= SandboxItem::Unknown; + } else + if (list[3].compare("I") == 0) + { + status |= SandboxItem::Ignored; + } else + { + // if nothing is outputted, the file is unchanged + status |= SandboxItem::Unchanged; + } + + // now determine if the file has been renamed + int from_id = list[4].toInt(); + int to_id = list[5].toInt(); + + // remove trailing slash + QString path = list[6]; + bool isDirectory = false; + if (path.endsWith("/")) + { + isDirectory = true; + path = path.left(path.length() - 1); + } + item = new SandboxItem(path, status, isDirectory); + + if (from_id > 0) + { + renameMap[-from_id] = item; + } + if (to_id > 0) + { + renameMap[to_id] = item; + } + tempItems->push_back(item); + } + + int id = 0; + + while (true) + { + renameIter = renameMap.find(++id); + if (renameIter == renameMap.end()) break; + + renameMap[id]->setRenamedFrom(renameMap[-id]); + renameMap[-id]->setRenamedTo(renameMap[id]); + } + + items = buildTreeRecursive(tempItems, NULL); + emit readyInventoryParsed(items); +} + +std::list* Sandbox::buildTreeRecursive(std::list* items, SandboxItem* parentItem) +{ + std::list *finalItems = new std::list(); + + SandboxItem *currentItem; + QString parentPath = ""; + + if (parentItem != NULL) + { + parentPath = parentItem->getPath(); + } + + while (items->size() > 0) + { + currentItem = items->front(); + + // + // if the item is not directly inside the current path stop immediately + // + QString tmpPath = parentPath; + tmpPath.append("/"); + tmpPath.append(currentItem->getFilename()); + + // path may not be empty for this condition + if (!parentPath.isEmpty() && currentItem->getPath().compare(tmpPath) != 0) + { + break; + } + + // remove the item if we can append it now + items->pop_front(); + + // + // it seems to be a valid item + // + // append item to final list + finalItems->push_back(currentItem); + + // if the item is directory a directory, make sure we catch decendant items... recursion! + if (currentItem->isDirectory()) + { + currentItem->setChildren(buildTreeRecursive(items, currentItem)); + } + } + return finalItems; +} + +std::list* Sandbox::getItems() +{ + return items; +} --- src/model/Sandbox.h +++ src/model/Sandbox.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef SANDBOX_H +#define SANDBOX_H + +#include +#include +#include +#include +#include +#include +#include + +#include "SandboxItem.h" +#include "Monotone.h" + +class Sandbox : public QObject +{ + Q_OBJECT + + public: + Sandbox(); + ~Sandbox(); + bool setWorkspaceDir(QString workspace); + bool readInventory(); + std::list* getItems(); + signals: + void readyInventoryParsed(std::list*); + private: + std::list* buildTreeRecursive(std::list*, SandboxItem*); + QDir *workspaceDir; + Monotone *monotone; + std::list *items; + private slots: + void parseInventory(int); +}; + +#endif --- src/model/SandboxItem.cpp +++ src/model/SandboxItem.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "SandboxItem.h" + +SandboxItem::SandboxItem() +{ + SandboxItem("", 0, FALSE); +} + +SandboxItem::SandboxItem(QString p, int st, bool isDir) +{ + status = st; + dirFlag = isDir; + path = p; + children = new std::list(); +} + +SandboxItem::~SandboxItem() {} + +void SandboxItem::setRenamedFrom(SandboxItem *to_item) +{ + renamed_from = to_item; +} + +SandboxItem* SandboxItem::getRenamedFrom() +{ + return renamed_from; +} + +SandboxItem* SandboxItem::getRenamedTo() +{ + return renamed_to; +} + +void SandboxItem::setRenamedTo(SandboxItem *from_item) +{ + renamed_to = from_item; +} + +void SandboxItem::setParent(SandboxItem *p) +{ + parent = p; +} + +SandboxItem* SandboxItem::getParent() +{ + return parent; +} + +void SandboxItem::addChild(SandboxItem* child) +{ + child->setParent(this); + children->push_back(child); +} + +void SandboxItem::setChildren(std::list *items) +{ + // set the current element as parent for each children + std::list::iterator iter; + + for (iter = items->begin(); iter != items->end(); ++iter) + { + (*iter)->setParent(this); + } + + children = items; +} + +std::list* SandboxItem::getChildren() +{ + return children; +} + +bool SandboxItem::isDirectory() +{ + return dirFlag; +} + +QString SandboxItem::getPath() +{ + return path; +} + +QString SandboxItem::getFilename() +{ + int pos = path.findRev('/'); + return pos == -1 ? path : path.right(path.length() - pos - 1); +} + +int SandboxItem::getStatus() +{ + return status; +} + +bool SandboxItem::hasStatus(int statusBits) +{ + return (status & statusBits) == statusBits; +} + +bool SandboxItem::hasNotStatus(int statusBits) +{ + return (status & statusBits) == 0; +} --- src/model/SandboxItem.h +++ src/model/SandboxItem.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef SANDBOX_ITEM_H +#define SANDBOX_ITEM_H + +#include +#include + +class SandboxItem +{ +public: + SandboxItem(); + SandboxItem(QString, int, bool); + ~SandboxItem(); + void setRenamedFrom(SandboxItem*); + void setRenamedTo(SandboxItem*); + SandboxItem* getRenamedFrom(); + SandboxItem* getRenamedTo(); + void setParent(SandboxItem*); + SandboxItem* getParent(); + void addChild(SandboxItem*); + void setChildren(std::list*); + std::list* getChildren(); + bool isDirectory(); + QString getPath(); + QString getFilename(); + int getStatus(); + bool hasStatus(int); + bool hasNotStatus(int); + + static const int RenamedFrom = 1; + static const int RenamedTo = 2; + static const int Added = 4; + static const int Dropped = 8; + static const int Missing = 16; + static const int Patched = 32; + static const int Unchanged = 64; + static const int Unknown = 128; + static const int Ignored = 256; +private: + SandboxItem *renamed_from; + SandboxItem *renamed_to; + SandboxItem *parent; + std::list *children; + int status; + bool dirFlag; + QString path; +}; + +#endif --- src/view/Guitone.cpp +++ src/view/Guitone.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#include "Guitone.h" + +Guitone::Guitone() + : QMainWindow( 0, "Guitone", WDestructiveClose ) +{ + // create sandbox object + mySandbox = new Sandbox(); + + // + // Menubar + // + QPopupMenu *fileMenu = new QPopupMenu(this); + menuBar()->insertItem( tr("&File"), fileMenu ); + + int id; + id = fileMenu->insertItem( + tr("&Import Sandbox..."), + this, + SLOT(chooseSandbox()), + CTRL+Key_I + ); + QString fileImportText = tr("Import a local sandbox into Guitone."); + fileMenu->setWhatsThis( id, fileImportText ); +/* + fileMenu->insertSeparator(); + + id = fileMenu->insertItem( + tr("&Quit"), + this, + SLOT(closeAllWindows()), + CTRL+Key_Q + ); + QString fileQuitText = tr("Quit Guitone."); + fileMenu->setWhatsThis( id, fileQuitText ); +*/ + // + // Main view + // + QSplitter *mainSplitter = new QSplitter(this); + treeView = new SandboxView(mainSplitter, SandboxView::FolderTree); + listView = new SandboxView(mainSplitter, SandboxView::FileList); + /* + QSplitter *rightSplitter = new QSplitter(mainSplitter); + rightSplitter->setOrientation(Qt::Vertical); + + listView = new SandboxView(rightSplitter, SandboxView::FileList); + logWindow = new QTextEdit(rightSplitter); + */ + + connect(treeView, SIGNAL(updateDisplay(std::list*)), + listView, SLOT(display(std::list*))); + + connect(treeView, SIGNAL(findAndSelectItem(SandboxItem*)), + this, SLOT(doFindAndSelectItem(SandboxItem*))); + connect(listView, SIGNAL(findAndSelectItem(SandboxItem*)), + this, SLOT(doFindAndSelectItem(SandboxItem*))); + + setCentralWidget(mainSplitter); + + resize( 450, 600 ); + + statusBar()->message( tr("Ready"), 2000 ); +} + + +Guitone::~Guitone() {} + + +void Guitone::chooseSandbox() +{ + QString fn = QFileDialog::getExistingDirectory( + QString::null, + this, + "select workspace dialog", + "Select your workspace...", + TRUE + ); + if (fn.isEmpty()) + { + statusBar()->message( tr("Loading aborted"), 2000 ); + return; + } + + if (!mySandbox->setWorkspaceDir(fn)) + { + QMessageBox::information( + this, + "Invalid workspace", + "The chosen directory is no monotone sandbox!", + QMessageBox::Ok + ); + return; + } + + connect( + mySandbox, SIGNAL(readyInventoryParsed(std::list*)), + treeView, SLOT(display(std::list*)) + ); + + if (!mySandbox->readInventory()) + { + QMessageBox::information( + this, + "Inventory could not be read", + "The inventory could not be read. Maybe another task is still running?", + QMessageBox::Ok + ); + return; + } + + statusBar()->message(tr("Loading workspace..."), 2000 ); +} + +void Guitone::doFindAndSelectItem(SandboxItem* sbItem) +{ + // the item is a normal directory... + if (sbItem->isDirectory()) + { + // we don't care if this succeeds or not, + // if it does not succeed, we don't know what to + // do otherwise anyways + treeView->selectItem(sbItem); + return; + } + + // check if the element can be selected in the current list + if (listView->selectItem(sbItem)) + { + return; + } + + // the item doesn't seem to be in the current list, + // lets try to select its parent first, this updates + // the list and we may have then luck and see the correct + // selected item + if (treeView->selectItem(sbItem->getParent())) + { + listView->selectItem(sbItem); + } +} --- src/view/Guitone.h +++ src/view/Guitone.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2006 by Thomas Keller * + * address@hidden * + * * + * 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 2 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#ifndef GUITONE_H +#define GUITONE_H + +#include "../model/Sandbox.h" +#include "../view/SandboxView.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QTextEdit; + +class Guitone: public QMainWindow +{ + Q_OBJECT + +public: + Guitone(); + ~Guitone(); +private slots: + void chooseSandbox(); + void doFindAndSelectItem(SandboxItem*); + +private: + QString determineStatus(SandboxItem*); + Sandbox *mySandbox; + SandboxView *treeView; + SandboxView *listView; + QTextEdit *logWindow; +}; + + +#endif --- src/view/SandboxView.cpp +++ src/view/SandboxView.cpp @@ -0,0 +1,324 @@ + +#include "SandboxView.h" + +SandboxView::SandboxView(QWidget* parent, int type) + : QListView(parent) +{ + rootItem = 0; + + itemPopup = new QPopupMenu(this); + viewPopup = new QPopupMenu(this); + viewPopup->setCheckable(true); + hideIgnoredItems_id = viewPopup->insertItem("Hide i&gnored items", this, SLOT(toggleHideIgnoredItems())); + + viewType = type; + + if (viewType == SandboxView::FileList) + { + addColumn("File"); + } + else + { + addColumn("Folder"); + setRootIsDecorated(true); + } + + // common for both views + addColumn("Status"); + + connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&,int)), + this, SLOT(openContextMenu(QListViewItem*, const QPoint&,int))); +} + +SandboxView::~SandboxView() {} + +void SandboxView::display(std::list* items) +{ + // clear lookup tables + lookupTable.clear(); + reverseLookupTable.clear(); + + // clear view + clear(); + + if (viewType == SandboxView::FileList) + { + displayFileList(items); + } + else + { + displayFolderTree(items); + } + + // show/hide ignored items (depending on the last setting) + bool hideIgnoredItems = viewPopup->isItemChecked(hideIgnoredItems_id); + showHideIgnoredItems(!hideIgnoredItems); +} + +void SandboxView::displayFileList(std::list* items) +{ + std::list::iterator iter; + QListViewItem *viewItem; + + for (iter= items->begin(); iter != items->end(); iter++) + { + if (!(*iter)->isDirectory()) + { + viewItem = new QListViewItem(this, (*iter)->getFilename(), determineItemStatus(*iter)); + lookupTable[viewItem] = *iter; + reverseLookupTable[*iter] = viewItem; + } + } +} + +void SandboxView::displayFolderTree(std::list* items) +{ + connect(this, SIGNAL(selectionChanged(QListViewItem*)), + this, SLOT(doUpdateFolderTree(QListViewItem*))); + + // clear lookup map + lookupTable.clear(); + // clear the view + clear(); + + // dummy root element + rootItem = new SandboxItem("ROOT", 0 , true); + rootItem->setChildren(items); + + QListViewItem *listViewRoot = new QListViewItem(this, "ROOT"); + listViewRoot->setPixmap(0, QPixmap(XPM::FolderOpened)); + + lookupTable[listViewRoot] = rootItem; + reverseLookupTable[rootItem] = listViewRoot; + + // fill tree recursive only with folders + displayFolderTreeRecursive(items, listViewRoot); + + // trigger signal to display files of the root element + emit updateDisplay(items); +} + +void SandboxView::displayFolderTreeRecursive(std::list* items, QListViewItem* parent) +{ + + QListViewItem *listItem; + std::list::iterator iter; + + for (iter= items->begin(); iter != items->end(); iter++) + { + // only add directories + if ((*iter)->isDirectory()) + { + listItem = new QListViewItem(parent, (*iter)->getFilename(),determineItemStatus(*iter)); + listItem->setPixmap(0, QPixmap(XPM::FolderClosed)); + + lookupTable[listItem] = *iter; + reverseLookupTable[*iter] = listItem; + displayFolderTreeRecursive((*iter)->getChildren(), listItem); + } + } +} + + +void SandboxView::doUpdateFolderTree(QListViewItem* treeItem) +{ + std::map::iterator iter; + + for (iter = lookupTable.begin(); iter != lookupTable.end(); iter++) + { + // reset the pixmaps of all other items + iter->first->setPixmap(0, QPixmap(XPM::FolderClosed)); + + if (iter->first == treeItem) + { + emit updateDisplay(iter->second->getChildren()); + } + } + + // set pixmap to OpenFolder for selected item + treeItem->setPixmap(0, QPixmap(XPM::FolderOpened)); +} + +QString SandboxView::determineItemStatus(SandboxItem* item) +{ + QStringList list; + + if (item->hasStatus(SandboxItem::RenamedFrom)) + { + list.append("Rename Source"); + } + if (item->hasStatus(SandboxItem::RenamedTo)) + { + list.append("Rename Target"); + } + if (item->hasStatus(SandboxItem::Added)) + { + list.append("Added"); + } + if (item->hasStatus(SandboxItem::Dropped)) + { + list.append("Dropped"); + } + if (item->hasStatus(SandboxItem::Missing)) + { + list.append("Missing"); + } + if (item->hasStatus(SandboxItem::Patched)) + { + list.append("Patched"); + } + if (item->hasStatus(SandboxItem::Unchanged)) + { + list.append("Unchanged"); + } + if (item->hasStatus(SandboxItem::Unknown)) + { + list.append("Unknown"); + } + if (item->hasStatus(SandboxItem::Ignored)) + { + list.append("Ignored"); + } + return list.join(", "); +} + +void SandboxView::openContextMenu(QListViewItem *item, const QPoint& pos, int col) +{ + std::map::iterator iter = lookupTable.find(item); + + // general, non-item-specific context menu? + if (iter == lookupTable.end()) + { + viewPopup->popup(pos); + return; + } + + SandboxItem *sbItem = iter->second; + + itemPopup->clear(); + int entry; + + if (sbItem->hasStatus(SandboxItem::Unknown)) + { + entry = itemPopup->insertItem("Add", this, SLOT(addItem(int))); + itemPopup->setItemParameter(entry, (int)sbItem); + } + + if (sbItem->hasNotStatus(SandboxItem::Ignored) && sbItem->hasNotStatus(SandboxItem::Unknown)) + { + entry = itemPopup->insertItem("Drop", this, SLOT(dropItem(int))); + itemPopup->setItemParameter(entry, (int)sbItem); + } + + if (sbItem->hasStatus(SandboxItem::RenamedFrom)) + { + entry = itemPopup->insertItem("Select Rename Target", this, SLOT(selectRenameTarget(int))); + itemPopup->setItemParameter(entry, (int)sbItem); + } + + if (sbItem->hasStatus(SandboxItem::RenamedTo)) + { + entry = itemPopup->insertItem("Select Rename Source", this, SLOT(selectRenameSource(int))); + itemPopup->setItemParameter(entry, (int)sbItem); + } + + if (sbItem->hasNotStatus(SandboxItem::Ignored) && sbItem->hasNotStatus(SandboxItem::Unchanged) && sbItem->hasNotStatus(SandboxItem::Unknown)) + { + entry = itemPopup->insertItem("Revert", this, SLOT(revertItem(int))); + itemPopup->setItemParameter(entry, (int)sbItem); + } + + // any commands added? + if (itemPopup->count() > 0) + { + itemPopup->popup(pos); + } +} + +void SandboxView::toggleHideIgnoredItems() +{ + bool hideIgnoredItems = viewPopup->isItemChecked(hideIgnoredItems_id); + hideIgnoredItems = !hideIgnoredItems; + viewPopup->setItemChecked(hideIgnoredItems_id, hideIgnoredItems); + + showHideIgnoredItems(!hideIgnoredItems); +} + +void SandboxView::showHideIgnoredItems(bool show) +{ + std::map::iterator iter; + for (iter = lookupTable.begin(); iter != lookupTable.end(); iter++) + { + if (iter->second->hasStatus(SandboxItem::Ignored)) + { + iter->first->setVisible(show); + } + } +} + +void SandboxView::addItem(int item) +{ + SandboxItem *sbItem = (SandboxItem*)item; + + QMessageBox::information(this,"Info", "No functioality yet, sorry!",QMessageBox::Ok); + + qDebug("Adding item %s", sbItem->getFilename().latin1()); +} + +void SandboxView::dropItem(int item) +{ + SandboxItem *sbItem = (SandboxItem*)item; + + QMessageBox::information(this,"Info", "No functioality yet, sorry!",QMessageBox::Ok); + + qDebug("Dropping item %s", sbItem->getFilename().latin1()); +} + +void SandboxView::revertItem(int item) +{ + SandboxItem *sbItem = (SandboxItem*)item; + + QMessageBox::information(this,"Info", "No functioality yet, sorry!",QMessageBox::Ok); + + qDebug("Reverting item %s", sbItem->getFilename().latin1()); +} + +void SandboxView::selectRenameSource(int item) +{ + SandboxItem *sbItem = (SandboxItem*)item; + emit findAndSelectItem(sbItem->getRenamedFrom()); +} + +void SandboxView::selectRenameTarget(int item) +{ + SandboxItem *sbItem = (SandboxItem*)item; + emit findAndSelectItem(sbItem->getRenamedTo()); +} + +bool SandboxView::selectItem(SandboxItem* sbItem) +{ + std::map::iterator iter; + iter = reverseLookupTable.find(sbItem); + + if (iter == reverseLookupTable.end()) + { + qDebug("Item not found in current view"); + return false; + } + + setSelected(iter->second, true); + // make sure item becomes "visible" to the user + // after it was selected + ensureItemVisible(iter->second); + return true; +} + +SandboxItem* SandboxView::getRootItem() +{ + if (rootItem == 0) + { + qWarning("Root item not set."); + return 0; + } + return rootItem; +} --- src/view/SandboxView.h +++ src/view/SandboxView.h @@ -0,0 +1,59 @@ +#ifndef SANDBOX_VIEW_H +#define SANDBOX_VIEW_H + +#include "XPM.h" +#include "../model/SandboxItem.h" + +#include +#include +#include +#include +#include + +class SandboxView : public QListView +{ + Q_OBJECT + + public: + SandboxView(QWidget*, int); + ~SandboxView(); + void setItems(std::list*); + bool selectItem(SandboxItem*); + + static const int FolderTree = 1; + static const int FileList = 2; + + public slots: + void display(std::list*); + SandboxItem* getRootItem(); + + private: + int viewType; + std::list* sandboxItems; + QPopupMenu *viewPopup; + QPopupMenu *itemPopup; + SandboxItem *rootItem; + int hideIgnoredItems_id; + QString determineItemStatus(SandboxItem*); + void showHideIgnoredItems(bool); + + void displayFileList(std::list*); + void displayFolderTree(std::list*); + void displayFolderTreeRecursive(std::list*, QListViewItem*); + std::map lookupTable; + std::map reverseLookupTable; + private slots: + void doUpdateFolderTree(QListViewItem*); + void openContextMenu(QListViewItem*, const QPoint&, int); + void toggleHideIgnoredItems(); + void addItem(int); + void dropItem(int); + void revertItem(int); + void selectRenameTarget(int); + void selectRenameSource(int); + signals: + void updateDisplay(std::list*); + void findAndSelectItem(SandboxItem*); +}; + +#endif --- src/view/XPM.cpp +++ src/view/XPM.cpp @@ -0,0 +1,56 @@ + +#include "XPM.h" + +const char* XPM::FolderClosed[] = +{ + "16 16 6 1", + " c None", + ". c #808080", + "+ c #C0C0C0", + "@ c #FFFF00", + "# c #FFFFFF", + "$ c #000000", + " ", + " ..... ", + " address@hidden@+. ", + "address@hidden@address@hidden ", + ".############.$ ", + "address@hidden@address@hidden@address@hidden@.$ ", + "address@hidden@address@hidden@address@hidden ", + "address@hidden@address@hidden@address@hidden@.$ ", + "address@hidden@address@hidden@address@hidden ", + "address@hidden@address@hidden@address@hidden@.$ ", + "address@hidden@address@hidden@address@hidden ", + "address@hidden@address@hidden@address@hidden@.$ ", + "..............$ ", + " $$$$$$$$$$$$$$ ", + " ", + " " +}; + +const char* XPM::FolderOpened[] = +{ + "16 16 6 1", + " c None", + ". c #808080", + "+ c #FFFFFF", + "@ c #C0C0C0", + "# c #FFFF00", + "$ c #000000", + " ", + " ..... ", + " .+++++. ", + " address@hidden@address@hidden ", + " address@hidden@address@hidden", + " address@hidden@address@hidden@address@hidden@.$", + ".............#.$", + "address@hidden", + "address@hidden@address@hidden@address@hidden", + " address@hidden@address@hidden@address@hidden", + " address@hidden@address@hidden@address@hidden", + " address@hidden@address@hidden@#.$$", + " ............$$", + " $$$$$$$$$$$$$", + " ", + " " +}; --- src/view/XPM.h +++ src/view/XPM.h @@ -0,0 +1,7 @@ + +class XPM +{ + public: + static const char* FolderClosed[]; + static const char* FolderOpened[]; +};