[svn-inject] Installing original source of fosdem-schedule upstream/0.3+ds
authorgregor herrmann <gregoa@debian.org>
Wed, 3 Feb 2010 20:26:31 +0000 (20:26 -0000)
committergregor herrmann <gregoa@debian.org>
Wed, 3 Feb 2010 20:26:31 +0000 (20:26 -0000)
168 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
Changelog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
data/26x26/fosdem.png [new file with mode: 0644]
data/40x40/fosdem.png [new file with mode: 0644]
data/48x48/fosdem.png [new file with mode: 0644]
data/64x64/fosdem.png [new file with mode: 0644]
data/Makefile [new file with mode: 0644]
data/maemo/fosdem-schedule.desktop [new file with mode: 0644]
docs/user-stories.txt [new file with mode: 0644]
fosdem-schedule.pro [new file with mode: 0644]
src/alarm/alarm.cpp [new file with mode: 0644]
src/alarm/alarm.h [new file with mode: 0644]
src/alarm/alarm.pro [new file with mode: 0644]
src/alarm/calendar.cpp [new file with mode: 0644]
src/alarm/calendar.h [new file with mode: 0644]
src/app/alarmdbus.cpp [new file with mode: 0644]
src/app/alarmdbus.h [new file with mode: 0644]
src/app/alarmdbusadaptor.cpp [new file with mode: 0644]
src/app/alarmdbusadaptorp.h [new file with mode: 0644]
src/app/app.pro [new file with mode: 0644]
src/app/appsettings.cpp [new file with mode: 0644]
src/app/appsettings.h [new file with mode: 0644]
src/app/main.cpp [new file with mode: 0644]
src/db.qrc [new file with mode: 0644]
src/fosdem.sqlite [new file with mode: 0644]
src/global.pri [new file with mode: 0644]
src/gui/about.ui [new file with mode: 0644]
src/gui/alarmdialog.cpp [new file with mode: 0644]
src/gui/alarmdialog.h [new file with mode: 0644]
src/gui/alarmdialog.ui [new file with mode: 0644]
src/gui/conflictdialogcontainer.cpp [new file with mode: 0644]
src/gui/conflictdialogcontainer.h [new file with mode: 0644]
src/gui/conflictsdialog.cpp [new file with mode: 0644]
src/gui/conflictsdialog.h [new file with mode: 0644]
src/gui/conflictsdialog.ui [new file with mode: 0644]
src/gui/daynavigatorwidget.cpp [new file with mode: 0644]
src/gui/daynavigatorwidget.h [new file with mode: 0644]
src/gui/daynavigatorwidget.ui [new file with mode: 0644]
src/gui/dayviewtabcontainer.cpp [new file with mode: 0644]
src/gui/dayviewtabcontainer.h [new file with mode: 0644]
src/gui/eventdialog.cpp [new file with mode: 0644]
src/gui/eventdialog.h [new file with mode: 0644]
src/gui/eventdialog.ui [new file with mode: 0644]
src/gui/favtabcontainer.cpp [new file with mode: 0644]
src/gui/favtabcontainer.h [new file with mode: 0644]
src/gui/gui.pro [new file with mode: 0644]
src/gui/importschedulewidget.cpp [new file with mode: 0644]
src/gui/importschedulewidget.h [new file with mode: 0644]
src/gui/importschedulewidget.ui [new file with mode: 0644]
src/gui/mainwindow.cpp [new file with mode: 0644]
src/gui/mainwindow.h [new file with mode: 0644]
src/gui/mainwindow.ui [new file with mode: 0644]
src/gui/mapwindow.cpp [new file with mode: 0644]
src/gui/mapwindow.h [new file with mode: 0644]
src/gui/mapwindow.ui [new file with mode: 0644]
src/gui/nowtabcontainer.cpp [new file with mode: 0644]
src/gui/nowtabcontainer.h [new file with mode: 0644]
src/gui/proxysettingsdialog.cpp [new file with mode: 0644]
src/gui/proxysettingsdialog.h [new file with mode: 0644]
src/gui/proxysettingsdialog.ui [new file with mode: 0644]
src/gui/roomstabcontainer.cpp [new file with mode: 0644]
src/gui/roomstabcontainer.h [new file with mode: 0644]
src/gui/searchhead.cpp [new file with mode: 0644]
src/gui/searchhead.h [new file with mode: 0644]
src/gui/searchhead.ui [new file with mode: 0644]
src/gui/searchtabcontainer.cpp [new file with mode: 0644]
src/gui/searchtabcontainer.h [new file with mode: 0644]
src/gui/tabcontainer.cpp [new file with mode: 0644]
src/gui/tabcontainer.h [new file with mode: 0644]
src/gui/tabcontainer.ui [new file with mode: 0644]
src/gui/tabwidget.cpp [new file with mode: 0644]
src/gui/tabwidget.h [new file with mode: 0644]
src/gui/trackstabcontainer.cpp [new file with mode: 0644]
src/gui/trackstabcontainer.h [new file with mode: 0644]
src/icons.qrc [new file with mode: 0644]
src/icons/alarm-offBig.png [new file with mode: 0644]
src/icons/alarm-onBig.png [new file with mode: 0644]
src/icons/brain-alone.png [new file with mode: 0644]
src/icons/collapse.png [new file with mode: 0644]
src/icons/compassBig.png [new file with mode: 0644]
src/icons/exclamation.png [new file with mode: 0644]
src/icons/expand.png [new file with mode: 0644]
src/icons/favourite-offBig.png [new file with mode: 0644]
src/icons/favourite-onBig.png [new file with mode: 0644]
src/icons/fosdem.png [new file with mode: 0644]
src/icons/info.png [new file with mode: 0644]
src/icons/search.png [new file with mode: 0644]
src/icons/settings.png [new file with mode: 0644]
src/maps.qrc [new file with mode: 0644]
src/maps/campus.png [new file with mode: 0644]
src/maps/rooms/H-WC.png [new file with mode: 0644]
src/maps/rooms/aw1105.png [new file with mode: 0644]
src/maps/rooms/aw1115.png [new file with mode: 0644]
src/maps/rooms/aw1117.png [new file with mode: 0644]
src/maps/rooms/aw1120.png [new file with mode: 0644]
src/maps/rooms/aw1121.png [new file with mode: 0644]
src/maps/rooms/aw1124.png [new file with mode: 0644]
src/maps/rooms/aw1125.png [new file with mode: 0644]
src/maps/rooms/aw1126.png [new file with mode: 0644]
src/maps/rooms/chavanne.png [new file with mode: 0644]
src/maps/rooms/ferrer.png [new file with mode: 0644]
src/maps/rooms/guillissen.png [new file with mode: 0644]
src/maps/rooms/h1301.png [new file with mode: 0644]
src/maps/rooms/h1302.png [new file with mode: 0644]
src/maps/rooms/h1308.png [new file with mode: 0644]
src/maps/rooms/h1309.png [new file with mode: 0644]
src/maps/rooms/h2111.png [new file with mode: 0644]
src/maps/rooms/h2213.png [new file with mode: 0644]
src/maps/rooms/h2214.png [new file with mode: 0644]
src/maps/rooms/infodesk.png [new file with mode: 0644]
src/maps/rooms/janson.png [new file with mode: 0644]
src/maps/rooms/lameere.png [new file with mode: 0644]
src/maps/rooms/not-available.png [new file with mode: 0644]
src/maps/rooms/thumbs/H-WC.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1105.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1115.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1117.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1120.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1121.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1124.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1125.png [new file with mode: 0644]
src/maps/rooms/thumbs/aw1126.png [new file with mode: 0644]
src/maps/rooms/thumbs/chavanne.png [new file with mode: 0644]
src/maps/rooms/thumbs/ferrer.png [new file with mode: 0644]
src/maps/rooms/thumbs/guillissen.png [new file with mode: 0644]
src/maps/rooms/thumbs/h1301.png [new file with mode: 0644]
src/maps/rooms/thumbs/h1302.png [new file with mode: 0644]
src/maps/rooms/thumbs/h1308.png [new file with mode: 0644]
src/maps/rooms/thumbs/h1309.png [new file with mode: 0644]
src/maps/rooms/thumbs/h2111.png [new file with mode: 0644]
src/maps/rooms/thumbs/h2213.png [new file with mode: 0644]
src/maps/rooms/thumbs/h2214.png [new file with mode: 0644]
src/maps/rooms/thumbs/infodesk.png [new file with mode: 0644]
src/maps/rooms/thumbs/janson.png [new file with mode: 0644]
src/maps/rooms/thumbs/lameere.png [new file with mode: 0644]
src/maps/rooms/ua2114.png [new file with mode: 0644]
src/mvc/conference.cpp [new file with mode: 0644]
src/mvc/conference.h [new file with mode: 0644]
src/mvc/delegate.cpp [new file with mode: 0644]
src/mvc/delegate.h [new file with mode: 0644]
src/mvc/event.cpp [new file with mode: 0644]
src/mvc/event.h [new file with mode: 0644]
src/mvc/eventmodel.cpp [new file with mode: 0644]
src/mvc/eventmodel.h [new file with mode: 0644]
src/mvc/mvc.pro [new file with mode: 0644]
src/mvc/room.cpp [new file with mode: 0644]
src/mvc/room.h [new file with mode: 0644]
src/mvc/track.cpp [new file with mode: 0644]
src/mvc/track.h [new file with mode: 0644]
src/mvc/treeview.cpp [new file with mode: 0644]
src/mvc/treeview.h [new file with mode: 0644]
src/orm/orm.pro [new file with mode: 0644]
src/orm/ormrecord.h [new file with mode: 0644]
src/schedule.en.xml [new file with mode: 0755]
src/sql/schedulexmlparser.cpp [new file with mode: 0644]
src/sql/schedulexmlparser.h [new file with mode: 0644]
src/sql/sql.pro [new file with mode: 0644]
src/sql/sqlengine.cpp [new file with mode: 0644]
src/sql/sqlengine.h [new file with mode: 0644]
src/src.pro [new file with mode: 0644]
src/test/main.cpp [new file with mode: 0644]
src/test/mvc/eventtest.cpp [new file with mode: 0644]
src/test/mvc/eventtest.h [new file with mode: 0644]
src/test/test.pro [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..24920f2
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,18 @@
+Authors of fosdem-schedule.
+
+  Copyright (C) 2010 Ixonos Plc. 
+
+  Copying and distribution of this file, with or without modification,
+  are permitted in any medium without royalty provided the copyright
+  notice and this notice are preserved.
+
+Francisco Fortes 
+Matus Hanzes 
+Martin Komara
+Marek Timko
+Matus Uzak
+Monika Berendova
+Pavol Korinek
+Pavol Pavelka 
+
+
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..d511905
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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.
+
+  <signature of Ty Coon>, 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 Lesser General
+Public License instead of this License.
diff --git a/Changelog b/Changelog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..e32aa70
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,39 @@
+This is the INSTALL file for the fosdem-schedule distribution.
+
+  Copyright (C) 2010 Ixonos Plc. 
+
+  Copying and distribution of this file, with or without modification,
+  are permitted in any medium without royalty provided the copyright
+  notice and this notice are preserved.
+
+NOTE
+====
+
+fosdem-schedule is an application intended for Nokia N810 and N900 Internet
+tablet devices.  Therefor the preferred distribution is a Debian package.
+Notice the different release of the Maemo platform on each of the devices,
+which requires a specific Debian package.  
+
+Maemo is a trademark of Nokia Corporation.  Debian is a registered trademark
+owned by SPI in the United States, and managed by the debian project, as
+explained on their site.
+
+Basic Installation
+==================
+
+1. Type `qmake' to generate Makefiles.
+2. Type `make' to compile the source code.
+3. Type `make install' to install the executable.  
+4. Type `make uninstall' to remove all installed files form your system.      
+
+Maemo Package Building 
+======================
+
+1. Type `qmake' to generate Makefiles.
+2. Check the "Build-Depends" section of the control file for required packages.
+   Maemo 3 (Diablo) specific:
+   - Ignore the version strings when building a package for Maemo 3 (Diablo).
+   - Optification of the package is not explicitly required, to disable it
+     comment out the "maemo-optify $(PKG_NAME)" line in debian/rules.  
+3. Type `dpkg-buildpackage -rfakeroot -b -uc' to build a package.  
\ No newline at end of file
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..fdaab92
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,19 @@
+
+This NEWS file records noteworthy changes, very tersely.
+
+Version 0.3 (3 Feb 2010)
+* Performance improvement for events. 
+
+Version 0.2 (2 Feb 2010)
+* Search tab has been added.
+* Alarms handled by alarmd, which requests native alarm dialogs (N900 only).
+* A service is registered to DBus, the application is handling calls from alarm
+  dialogs to reflect alarm states into the database.  The application is
+  started if required (N900 only).
+
+Version 0.1 (19 Jan 2010) 
+* A user can select favourite events, which are displayed in "Favourites" tab.
+* FOSDEM icon is displayed in application manager and in applications menu.        
+* Optification of the package is done using maemo-optify script.
+* There is now a `NEWS' file (this one), giving a history of
+  user-visible changes.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..f8f46f8
--- /dev/null
+++ b/README
@@ -0,0 +1,52 @@
+This is the README file for the fosdem-schedule distribution.  
+
+  Copyright (C) 2010 Ixonos Plc. 
+
+  Copying and distribution of this file, with or without modification,
+  are permitted in any medium without royalty provided the copyright
+  notice and this notice are preserved.
+
+fosdem-schedule is an application written in Qt, which makes the FOSDEM
+conference schedule available offline.  It displays the conference schedule
+from various views, support searches on various items (speaker, speech topic,
+location, etc.) and enables you to select favorite events and create your own
+schedule.  For Nokia N810 and N900.
+
+See the file ./INSTALL for building and installation instructions.
+
+Primary distribution point: http://sourceforge.net/projects/fosdem-maemo/
+
+Home page: http://sourceforge.net/apps/mediawiki/fosdem-maemo/
+
+Mailing list: fosdem-maemo-devel@lists.sourceforge.net
+- please use this list for all discussion: bug reports, enhancements, etc.
+- archived at: http://sourceforge.net/mailarchive/forum.php?forum_name=fosdem-maemo-devel
+- anyone is welcome to join the list; to do so, visit
+  https://lists.sourceforge.net/lists/listinfo/fosdem-maemo-devel
+
+Bug reports:
+ Please include enough information for the maintainers to reproduce the
+ problem.  Generally speaking, that means:
+- the contents of any input files necessary to reproduce the bug
+  and command line invocations of the program(s) involved (crucial!).
+- a description of the problem and any samples of the erroneous output.
+- the version number of the program(s) involved (use --version).
+- hardware, operating system, and compiler versions (uname -a).
+- anything else that you think would be helpful.
+
+Patches are most welcome; if possible, please make them with diff -c and
+include ChangeLog entries.
+
+fosdem-schedule is free software.  See the file COPYING for copying conditions.
+
+About FOSDEM 2010:
+
+The tenth FOSDEM is a two-day event organized by volunteers to promote the
+widespread use of Free and Open Source software.  Taking place in the beautiful
+city of Brussels (Belgium), FOSDEM meetings are recognized as "The best Free
+Software and Open Source events in Europe".
+
+FOSDEM name and FOSDEM brain icon are Trademarks of FOSDEM ASBL, which gave
+this project the rights to use the brain icon and name.  Copying and
+distribution of the FOSDEM brain icon must follow the Creative Commons
+Attribution-Noncommercial-No Derivative Works 2.0 Belgium License.
\ No newline at end of file
diff --git a/data/26x26/fosdem.png b/data/26x26/fosdem.png
new file mode 100644 (file)
index 0000000..e441ff7
Binary files /dev/null and b/data/26x26/fosdem.png differ
diff --git a/data/40x40/fosdem.png b/data/40x40/fosdem.png
new file mode 100644 (file)
index 0000000..e18ef7c
Binary files /dev/null and b/data/40x40/fosdem.png differ
diff --git a/data/48x48/fosdem.png b/data/48x48/fosdem.png
new file mode 100644 (file)
index 0000000..a1a6c0b
Binary files /dev/null and b/data/48x48/fosdem.png differ
diff --git a/data/64x64/fosdem.png b/data/64x64/fosdem.png
new file mode 100644 (file)
index 0000000..adb7231
Binary files /dev/null and b/data/64x64/fosdem.png differ
diff --git a/data/Makefile b/data/Makefile
new file mode 100644 (file)
index 0000000..c5a1429
--- /dev/null
@@ -0,0 +1,40 @@
+# Makefile - install Maemo specific data files 
+
+PKG            = fosdem-schedule
+ICON           = fosdem
+PREFIX         = $(INSTALL_ROOT)/usr/share
+INSTALL_FILE   = install -m 644 -p
+CHK_DIR                = test -d
+MKDIR          = mkdir -p
+
+.PHONY: install uninstall clean distclean
+
+all:
+
+install: 
+       $(CHK_DIR) $(PREFIX)/applications/hildon/ || $(MKDIR) $(PREFIX)/applications/hildon/ 
+       $(INSTALL_FILE) ./maemo/$(PKG).desktop $(PREFIX)/applications/hildon/
+
+       $(CHK_DIR) $(PREFIX)/icons/hicolor/26x26/hildon/ || $(MKDIR) $(PREFIX)/icons/hicolor/26x26/hildon/ 
+       $(INSTALL_FILE) ./26x26/$(ICON).png $(PREFIX)/icons/hicolor/26x26/hildon/
+
+       $(CHK_DIR) $(PREFIX)/icons/hicolor/48x48/hildon/ || $(MKDIR) $(PREFIX)/icons/hicolor/48x48/hildon/ 
+       $(INSTALL_FILE) ./48x48/$(ICON).png $(PREFIX)/icons/hicolor/48x48/hildon/
+
+       $(CHK_DIR) $(PREFIX)/icons/hicolor/40x40/hildon/ || $(MKDIR) $(PREFIX)/icons/hicolor/40x40/hildon/ 
+       $(INSTALL_FILE) ./40x40/$(ICON).png $(PREFIX)/icons/hicolor/40x40/hildon/
+
+       $(CHK_DIR) $(PREFIX)/icons/hicolor/64x64/hildon/ || $(MKDIR) $(PREFIX)/icons/hicolor/64x64/hildon/
+       $(INSTALL_FILE) ./64x64/$(ICON).png $(PREFIX)/icons/hicolor/64x64/hildon/
+
+
+uninstall:
+       $(RM) $(PREFIX)/applications/hildon/$(PKG).desktop
+       $(RM) $(PREFIX)/icons/hicolor/26x26/hildon/$(ICON).png
+       $(RM) $(PREFIX)/icons/hicolor/40x40/hildon/$(ICON).png
+       $(RM) $(PREFIX)/icons/hicolor/48x48/hildon/$(ICON).png
+       $(RM) $(PREFIX)/icons/hicolor/64x64/hildon/$(ICON).png
+
+clean:
+
+distclean:
diff --git a/data/maemo/fosdem-schedule.desktop b/data/maemo/fosdem-schedule.desktop
new file mode 100644 (file)
index 0000000..6339f70
--- /dev/null
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=0.3
+Type=Application
+Name=FOSDEM'10
+Exec=/usr/bin/fosdem-schedule
+Icon=fosdem
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
+
diff --git a/docs/user-stories.txt b/docs/user-stories.txt
new file mode 100644 (file)
index 0000000..847366b
--- /dev/null
@@ -0,0 +1,22 @@
+\r
+As an user I would like to have following features available in FOSDEM application:\r
+o   I\92d like to see all events for current day (default: current time)\r
+o   I\92d like to see all events for other days \r
+o   I\92d like to see all events grouped by activity\r
+o   I\92d like to see all events grouped by room\r
+o   I\92d like to see all details about selected event\r
+o   In detail view, I\92d like to have option  to show room on the map\r
+o   If there are some links in the event detail, I\92d like to have option to open link in browser\r
+o   In detail view, I\92d like to add/remove event to/from favorites\r
+o   I\92d like to search events by title/abstract, speaker name, tags, activity category, room number/name\r
+o   I\92d like to see my favorite events\r
+o   I\92d like to be noticed when some of my favorite events are overlapping\r
+o   I\92d like to add reminder into calendar for selected event\r
+o   I\92d like to see which events are added to calendar or to favorites\r
+o   I\92d like to option to update list of events through the web \r
+--------------------------------------------------------------------\r
+o   I'd like to have "my track" -- the personal schedule of events the user would like to attend.\r
+o   I wish to have "now button" to show me what's ongoing now.\r
+====================================================================\r
+o   I'd like to have possibility to post to eg. twitter or facebook -- some button to easy post on twitter "I'm attending now this". \r
+\r
diff --git a/fosdem-schedule.pro b/fosdem-schedule.pro
new file mode 100644 (file)
index 0000000..8896386
--- /dev/null
@@ -0,0 +1,11 @@
+# fosdem-schedule.pro
+
+QMAKEVERSION = $$[QMAKE_VERSION]
+ISQT4 = $$find(QMAKEVERSION, ^[2-9])
+isEmpty( ISQT4 ) {
+error("Use the qmake include with Qt4.4 or greater, on Debian that is
+qmake-qt4");
+}
+
+TEMPLATE = subdirs
+SUBDIRS = data src
diff --git a/src/alarm/alarm.cpp b/src/alarm/alarm.cpp
new file mode 100644 (file)
index 0000000..0cfb31b
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "alarm.h"
+
+#include <QDateTime>
+
+#include <QApplication>
+#include <QDir>
+#include <QFileInfo>
+
+#include <QDebug>
+
+//#include <dbus-1.0/dbus/dbus-protocol.h>
+
+int Alarm::addAlarm(int aEventId, const QDateTime &aDateTime)
+{
+    cookie_t cookie = 0;
+    alarm_event_t *eve = 0;
+    alarm_action_t *act = 0;
+
+    /* Create alarm event structure and set application identifier */
+    eve = alarm_event_create();
+    alarm_event_set_alarm_appid(eve, APPID);
+
+    /* for Deleting purposes */
+    alarm_event_set_message(eve, QString::number(aEventId).toLocal8Bit().data());
+
+    /* Use absolute time triggering */
+    //eve->alarm_time = time(0) + 5; // for testing (5 seconds from now)
+    eve->alarm_time = aDateTime.toTime_t();
+    eve->flags = ALARM_EVENT_BOOT;
+
+    /* Add exec command action */
+    act = alarm_event_add_actions(eve, 1);
+    alarm_action_set_label(act, "FOSDEM'10");
+
+    QString command = QFileInfo(*qApp->argv()).absoluteFilePath() + QString(" %1").arg(QString::number(aEventId));
+    qDebug() << "Setting alarm: " << command;
+    alarm_action_set_exec_command(act, command.toLocal8Bit().data());
+    act->flags |= ALARM_ACTION_TYPE_EXEC;
+    act->flags |= ALARM_ACTION_WHEN_RESPONDED;
+    act->flags |= ALARM_ACTION_EXEC_ADD_COOKIE; // adds assigned cookie at the end of command string
+
+//    // setup this action to be a "DBus command"
+//    act->flags |= ALARM_ACTION_WHEN_RESPONDED;
+//    act->flags |= ALARM_ACTION_TYPE_DBUS;
+//
+//    // DBus params for this action
+//    alarm_action_set_dbus_interface(act, "org.fosdem.schedule.AlarmInterface");
+//    alarm_action_set_dbus_service(act, "org.fosdem.schedule");
+//    alarm_action_set_dbus_path(act, "/Fosdem");
+//    alarm_action_set_dbus_name(act, "Alarm");
+//
+//    // DBus arguments for the action
+//    alarm_action_set_dbus_args(act,  DBUS_TYPE_INT32, &aEventId, DBUS_TYPE_INVALID);
+
+    //    act->flags |= ALARM_ACTION_TYPE_EXEC;
+    //     alarm_action_set_exec_command(act, command.toLocal8Bit().data());
+    //    alarm_event_set_icon(eve, "fosdem");
+    //    alarm_event_set_title(eve, "FOSDEM'10");
+    // adds assigned cookie at the end of command string
+    //    act->flags |= ALARM_ACTION_EXEC_ADD_COOKIE;
+
+    /* Add stop button action */
+    /* TODO: send a DBus message to remove that alarm from database */
+    act = alarm_event_add_actions(eve, 1);
+    alarm_action_set_label(act, "Stop");
+    act->flags |= ALARM_ACTION_WHEN_RESPONDED;
+    act->flags |= ALARM_ACTION_TYPE_NOP;
+
+    /* Add snooze button action */
+    act = alarm_event_add_actions(eve, 1);
+    alarm_action_set_label(act, "Snooze");
+    act->flags |= ALARM_ACTION_WHEN_RESPONDED;
+    act->flags |= ALARM_ACTION_TYPE_SNOOZE;
+
+    /* Send the alarm to alarmd */
+    cookie = alarmd_event_add(eve);
+
+    // adding alarm failed
+    if (cookie == 0)
+        emit(addAlarmFailed(aEventId));
+    else
+        emit(alarmAdded(aEventId));
+
+    /* Free all dynamic memory associated with the alarm event */
+    alarm_event_delete(eve);
+
+    return cookie;
+}
+
+void Alarm::deleteAlarm(int aEventId)
+{
+    cookie_t *list = 0;
+    cookie_t cookie = 0;
+    alarm_event_t *event = 0;
+
+    // query the APPID's list of alarms
+    if( (list = alarmd_event_query(0,0, 0,0, APPID)) != 0 ) // query OK
+    {
+        for( int i = 0; (cookie = list[i]) != 0; ++i )
+        {
+            alarm_event_delete(event);
+
+            // get the event for specified alarm cookie (alarmId)
+            if( (event = alarmd_event_get(cookie)) == 0 )
+            {
+                // should we inform user about it ???
+                continue;
+            }
+
+            if(aEventId==atoi(alarm_event_get_message(event)))
+            {
+                // delete cookie
+                if( alarmd_event_del(cookie) == -1 )
+                {
+                    // was not able to delete alarm for given aEventId
+                    emit(deleteAlarmFailed(aEventId));
+                    break;
+                }
+                else
+                {
+                    emit(alarmDeleted(aEventId));
+                    break;
+                }
+            }
+        }
+    }
+    else
+    {
+        // query failed
+    }
+
+    free(list);
+    alarm_event_delete(event);
+}
+
+bool Alarm::hasEventAlarm(int aEventId)
+{
+    cookie_t *list = 0;
+    cookie_t cookie = 0;
+    alarm_event_t *event = 0;
+
+    bool eventHasAlarm = false;
+
+    // query the APPID's list of alarms
+    if( (list = alarmd_event_query(0,0, 0,0, APPID)) != 0 ) // query OK
+    {
+        for( int i = 0; (cookie = list[i]) != 0; ++i )
+        {
+            alarm_event_delete(event);
+
+            // get the event for specified alarm cookie (alarmId)
+            if( (event = alarmd_event_get(cookie)) == 0 )
+            {
+                // should we inform user about it ???
+                continue;
+            }
+
+            if(aEventId==atoi(alarm_event_get_message(event)))
+            {
+                eventHasAlarm = true;
+                break;
+            }
+        }
+    }
+    else
+    {
+        // query failed
+    }
+
+    free(list);
+    alarm_event_delete(event);
+
+    return eventHasAlarm;
+}
+
diff --git a/src/alarm/alarm.h b/src/alarm/alarm.h
new file mode 100644 (file)
index 0000000..23004aa
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef ALARM_H
+#define ALARM_H
+
+#include <QObject>
+#include <QDateTime>
+
+extern "C"
+{
+#include <alarmd/libalarm.h>
+}
+
+#define APPID "fosdem-alarm"
+
+class Alarm : public QObject
+{
+    Q_OBJECT
+    public:
+        Alarm() {}
+        ~Alarm() {}
+        int addAlarm(int aEventId, const QDateTime &aDateTime); 
+        void deleteAlarm(int aEventId);
+        static bool hasEventAlarm(int aEventId);
+    signals:
+        void alarmAdded(int aEventId);
+        void addAlarmFailed(int aEventId);
+        void alarmDeleted(int aEventId);
+        void deleteAlarmFailed(int aEventId);
+};
+
+#endif /* ALARM_H */
+
diff --git a/src/alarm/alarm.pro b/src/alarm/alarm.pro
new file mode 100644 (file)
index 0000000..0db75aa
--- /dev/null
@@ -0,0 +1,21 @@
+TEMPLATE = lib
+TARGET = qalarm
+DESTDIR = ../bin
+CONFIG += static qdbus 
+QT += sql dbus
+
+# module dependencies
+LIBS += -lalarm
+DEPENDPATH += .
+
+HEADERS += alarm.h \
+
+SOURCES += alarm.cpp \
+
+INCLUDEPATH += ../gui \
+    ../mvc \ 
+    ../orm \
+    ../sql
+    
+
+
diff --git a/src/alarm/calendar.cpp b/src/alarm/calendar.cpp
new file mode 100644 (file)
index 0000000..34c165d
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "calendar.h"
+#include <qdebug.h>
+#include <qvariant.h>
+
+#include <calendar-backend/CMulticalendar.h>
+#include <calendar-backend/CCalendar.h>
+#include <calendar-backend/CEvent.h>
+#include <calendar-backend/CAlarm.h>
+
+Calendar::Calendar():
+m_pMultiCalendar(0),
+m_pCalendar(0)
+{
+       m_pMultiCalendar = CMulticalendar::MCInstance();
+
+       if(m_pMultiCalendar != NULL)
+               m_pCalendar  = m_pMultiCalendar->getSynchronizedCalendar();
+
+}
+
+Calendar::~Calendar()
+{
+       delete m_pCalendar;
+       delete m_pMultiCalendar;
+}
+
+int Calendar::addCalendarEvent(QString summary, QString description, QString location, uint dateStart, uint  dateEnd, int eventId)
+{
+       int errorCode = 0;
+
+       if(m_pMultiCalendar == NULL)
+               return 0;
+
+       if(m_pCalendar == NULL)
+               return 0;
+
+       // create event
+       CEvent event(summary.toStdString(), description.toStdString(), location.toStdString(),  dateStart, dateEnd);
+
+       // create alarm
+       CAlarm alarm;
+       alarm.setTrigger(dateStart - 15 * 60);
+       alarm.setRepeat(1);
+       alarm.setDuration(3);
+       alarm.setAction(0);
+       alarm.setAttach(QString::number(eventId).toLocal8Bit().data());
+
+       // add alarm to event
+       event.setAlarm(&alarm);
+
+       // register event into calendar
+       m_pMultiCalendar->addEvent(&event,m_pCalendar->getCalendarId(),errorCode);
+
+    return errorCode;
+}
+
+void Calendar::deleteCalendarEvent(uint dateStart, uint dateEnd, int eventId)
+{
+       int errorCode = 0;
+
+       vector< CComponent * > components;
+
+       // get all events
+       components = m_pMultiCalendar->getComponents(m_pCalendar->getCalendarId(), 1, dateStart, dateEnd, errorCode);
+
+       for (vector<CComponent *>::iterator it = components.begin();it!=components.end(); ++it)
+       {
+               // get alarm properties
+               if( (*it)->getAlarmProperties() == true)
+               {
+                       CAlarm * pAlarm = (*it)->getAlarm();
+
+                       bool converted = false;
+                       int tempId = QVariant(pAlarm->getAttach().data()).toInt(&converted);
+
+                       // check event id
+                       if(converted == true)
+                               if(tempId == eventId)
+                               {
+                                       //delete event
+                                       m_pCalendar->deleteComponent((*it)->getId(),errorCode);
+                                       break;
+                               }
+               }
+       }
+}
+
+bool Calendar::hasCalendarEvent(int eventId)
+{
+       bool ret = false;
+       int errorCode = 0;
+
+       vector< CEvent * > events;
+
+       // get all events
+       events = m_pCalendar->getEvents(errorCode);
+
+       if(events.size() > 0)
+       {
+               for (vector<CEvent *>::iterator it = events.begin(); it!=events.end(); ++it)
+               {
+                       // get alarm properties
+                       if( (*it)->getAlarmProperties() == true)
+                       {
+                               CAlarm * pAlarm = (*it)->getAlarm();
+
+                               bool converted = false;
+                               int tempId = QVariant(pAlarm->getAttach().data()).toInt(&converted);
+
+                               // check event id
+                               if(converted == true)
+                                       if(tempId == eventId)
+                                       {
+                                               ret = true;
+                                               break;
+                                       }
+                       }
+               }
+       }
+}
diff --git a/src/alarm/calendar.h b/src/alarm/calendar.h
new file mode 100644 (file)
index 0000000..66eecfa
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef CALENDAR_H
+#define CALENDAR_H
+
+#include <QObject>
+#include <QDateTime>
+
+class CMulticalendar;
+class CCalendar;
+
+class Calendar : public QObject
+{
+    Q_OBJECT
+    public:
+       Calendar();
+        ~Calendar();
+        int addCalendarEvent(QString summary, QString description, QString location, uint dateStart, uint dateEnd, int eventId);
+        void deleteCalendarEvent(uint dateStart, uint dateEnd, int eventId);
+        bool hasCalendarEvent(int eventId);
+
+        CMulticalendar * m_pMultiCalendar;
+        CCalendar * m_pCalendar;
+//    signals:
+//        void alarmAdded(int aEventId);
+//        void addAlarmFailed(int aEventId);
+//        void alarmDeleted(int aEventId);
+//        void deleteAlarmFailed(int aEventId);
+};
+
+#endif /* CALENDAR_H */
diff --git a/src/app/alarmdbus.cpp b/src/app/alarmdbus.cpp
new file mode 100644 (file)
index 0000000..18aeed8
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "alarmdbus.h"
+#include "eventdialog.h"
+
+
+
+
+CAlarmDBus::CAlarmDBus(QWidget * aParent)
+    : QObject(),
+    mParent(aParent)
+{
+    // constructor
+    //setAutoRelaySignals(true);
+}
+
+CAlarmDBus::~CAlarmDBus()
+{
+    // destructor
+}
+
+void CAlarmDBus::Alarm(int aEventId)
+{
+       EventDialog dialog(aEventId,mParent);
+       dialog.exec();
+
+}
diff --git a/src/app/alarmdbus.h b/src/app/alarmdbus.h
new file mode 100644 (file)
index 0000000..2e538c7
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef ALARM_DBUS_H
+#define ALARM_DBUS_H
+
+#include <QObject>
+#include <QtDBus/QtDBus>
+
+class CAlarmDBus: public QObject
+{
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "org.fosdem.schedule")
+
+public:
+       CAlarmDBus(QWidget * aParent);
+    virtual ~CAlarmDBus();
+
+public: // PROPERTIES
+public Q_SLOTS: // METHODS
+    void Alarm(int aEventId);
+private:
+       QWidget * mParent;
+};
+
+
+#endif // ALARM_DBUS_H
diff --git a/src/app/alarmdbusadaptor.cpp b/src/app/alarmdbusadaptor.cpp
new file mode 100644 (file)
index 0000000..95e5aa5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "alarmdbusadaptorp.h"
+#include <QtCore/QMetaObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+
+
+AlarmDBusAdaptor::AlarmDBusAdaptor(QObject *parent)
+    : QDBusAbstractAdaptor(parent)
+{
+    // constructor
+    setAutoRelaySignals(true);
+}
+
+AlarmDBusAdaptor::~AlarmDBusAdaptor()
+{
+    // destructor
+}
+
+void AlarmDBusAdaptor::Alarm(int aEventId)
+{
+    QMetaObject::invokeMethod(parent(), "Alarm",Q_ARG(int, aEventId));
+}
+
+
diff --git a/src/app/alarmdbusadaptorp.h b/src/app/alarmdbusadaptorp.h
new file mode 100644 (file)
index 0000000..4e1e105
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef ALARM_DBUS_ADAPTOR_P_H
+#define ALARM_DBUS_ADAPTOR_P_H
+
+#include <QtCore/QObject>
+#include <QtDBus/QtDBus>
+
+QT_BEGIN_NAMESPACE
+class QByteArray;
+template<class T> class QList;
+template<class Key, class Value> class QMap;
+class QString;
+class QStringList;
+class QVariant;
+QT_END_NAMESPACE
+
+
+class AlarmDBusAdaptor: public QDBusAbstractAdaptor
+{
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "org.fosdem.schedule.AlarmInterface")
+    Q_CLASSINFO("D-Bus Introspection", ""
+"  <interface name=\"org.fosdem.schedule.AlarmInterface\" >\n"
+"  <method name=\"Alarm\">\n"
+"        <arg name=\"aEventId\" type=\"i\" direction=\"in\"/>\n"
+"  </method>\n"
+"  </interface>\n"
+        "")
+public:
+       AlarmDBusAdaptor(QObject *parent);
+    virtual ~AlarmDBusAdaptor();
+
+public: // PROPERTIES
+public Q_SLOTS: // METHODS
+       void Alarm(int aEventId);
+};
+
+#endif
diff --git a/src/app/app.pro b/src/app/app.pro
new file mode 100644 (file)
index 0000000..7d2d479
--- /dev/null
@@ -0,0 +1,37 @@
+include(../global.pri)
+TEMPLATE = app
+TARGET = fosdem-schedule
+DESTDIR = ../bin
+QT += sql xml network dbus 
+
+# module dependencies
+LIBS += -L$$DESTDIR -lgui -lmvc -lsql
+INCLUDEPATH += ../gui ../sql ../mvc ../orm
+DEPENDPATH += . ../gui
+TARGETDEPS += $$DESTDIR/libmvc.a $$DESTDIR/libgui.a $$DESTDIR/libsql.a
+maemo {
+    LIBS += -L$$DESTDIR -lqalarm -lalarm
+    INCLUDEPATH += ../alarm
+    DEPENDPATH +=  ../alarm
+    TARGETDEPS += $$DESTDIR/libqalarm.a
+}
+
+HEADERS += appsettings.h \
+    alarmdbus.h \
+       alarmdbusadaptorp.h
+
+SOURCES += main.cpp \
+           appsettings.cpp \
+    alarmdbus.cpp \
+       alarmdbusadaptor.cpp
+
+RESOURCES += ../icons.qrc \
+             ../maps.qrc \
+             ../db.qrc
+
+# instalation related
+
+PREFIX = /usr/bin
+INSTALLS = target
+target.path = $$PREFIX
+
diff --git a/src/app/appsettings.cpp b/src/app/appsettings.cpp
new file mode 100644 (file)
index 0000000..5ad4761
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "appsettings.h"
+
+const QString PROXY_ADDRESS_SETTING ("proxyAddress"); 
+const QString PROXY_PORT_SETTING ("proxyPort"); 
+const QString PROXY_ISDIRECT_SETTING ("proxyIsDirectConnection"); 
+
+QSettings AppSettings::mSettings("Ixonos", "FOSDEM");
+
+QString AppSettings::proxyAddress()
+{
+    return mSettings.value(PROXY_ADDRESS_SETTING).toString();
+}
+
+quint16 AppSettings::proxyPort()
+{
+    return mSettings.value(PROXY_PORT_SETTING).toUInt();
+}
+
+bool AppSettings::isDirectConnection()
+{
+    return mSettings.value(PROXY_ISDIRECT_SETTING).toBool();
+}
+
+void AppSettings::setProxyAddress(const QString &aAddress)
+{
+    mSettings.setValue(PROXY_ADDRESS_SETTING, aAddress);
+}
+
+void AppSettings::setProxyPort(const quint16 aPort)
+{
+    mSettings.setValue(PROXY_PORT_SETTING, aPort);
+}
+
+void AppSettings::setDirectConnection(bool aDirectConnection)
+{
+    mSettings.setValue(PROXY_ISDIRECT_SETTING, aDirectConnection);
+}
+
+bool AppSettings::contains(const QString &aKey)
+{
+    return mSettings.contains(aKey);
+}
+
diff --git a/src/app/appsettings.h b/src/app/appsettings.h
new file mode 100644 (file)
index 0000000..1b284de
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef APPSETTINGS_H
+#define APPSETTINGS_H
+
+#include <QString>
+#include <QSettings>
+
+class AppSettings
+{
+    private:
+        AppSettings() {}
+        static QSettings mSettings;
+
+    public:
+        static bool contains(const QString &aKey);
+
+        static QString proxyAddress();
+        static quint16 proxyPort();
+        static bool isDirectConnection();
+
+        static void setProxyAddress(const QString &aAddress);
+        static void setProxyPort(const quint16 aPort);
+        static void setDirectConnection(bool aDirectConnection);
+};
+
+#endif /* APPSETTINGS_H */
+
diff --git a/src/app/main.cpp b/src/app/main.cpp
new file mode 100644 (file)
index 0000000..777a0fc
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <mainwindow.h>
+
+#include <QtGui/QApplication>
+#include <sqlengine.h>
+
+#include "eventdialog.h"
+
+#ifdef MAEMO
+//#include <alarmdialog.h>
+#include <alarmdbus.h>
+#include <alarmdbusadaptorp.h>
+#endif /* MAEMO */
+
+
+int main(int argc, char *argv[])
+{
+    Q_INIT_RESOURCE(icons);
+    Q_INIT_RESOURCE(maps);
+    Q_INIT_RESOURCE(db);
+
+    QApplication a(argc, argv);
+    QApplication::setWindowIcon(QIcon(":/icons/fosdem.png"));
+
+    SqlEngine::initialize(); // creates "SQLITE" DB connection
+
+    QWidget *window;
+
+    window = new MainWindow;
+
+
+#ifdef MAEMO
+    // Alarm Dbus
+    CAlarmDBus *alarmDBus = new CAlarmDBus(window);
+    new AlarmDBusAdaptor(alarmDBus);
+    QDBusConnection connection = QDBusConnection::sessionBus();
+
+    if(connection.registerObject("/Fosdem", alarmDBus) == true)
+    {
+       if( connection.registerService("org.fosdem.schedule") == false)
+       {
+               if(argc>1)
+               {
+                       QDBusInterface *interface = new QDBusInterface("org.fosdem.schedule",
+                                                                      "/Fosdem",
+                                                                      "org.fosdem.schedule.AlarmInterface",
+                                                                      connection);
+                       interface->call("Alarm",atoi(argv[1]));
+                       return 0;
+               }
+       }
+    }
+
+    if(argc > 1)
+    {
+        EventDialog dialog(atoi(argv[1]),window);
+        dialog.exec();
+    }
+#endif
+
+    window->show();
+
+    return a.exec();
+}
+
diff --git a/src/db.qrc b/src/db.qrc
new file mode 100644 (file)
index 0000000..37282e0
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>fosdem.sqlite</file>
+</qresource>
+</RCC>
+
diff --git a/src/fosdem.sqlite b/src/fosdem.sqlite
new file mode 100644 (file)
index 0000000..97d6ada
Binary files /dev/null and b/src/fosdem.sqlite differ
diff --git a/src/global.pri b/src/global.pri
new file mode 100644 (file)
index 0000000..468a028
--- /dev/null
@@ -0,0 +1,22 @@
+# This is 'global.pri' file which defines
+# GLOBAL definitions for the project
+# include this file in each "*.pro" file, where it's needed
+# USAGE: include(./global.pri)
+
+# Define 'MAEMO' specific CONFIG/DEFINE
+# To handle 'MAEMO' specific soruces/code
+DISTRO = $$system(cat /etc/issue)
+contains( DISTRO, [Mm]aemo ) {
+    # for 'MAEMO' specific source code parts
+    DEFINES += MAEMO
+    # for eg. including 'MAEMO' specific files
+    CONFIG += maemo
+}
+
+contains( DISTRO, [Ii]nternet ) {
+    contains( DISTRO, [Tt]ablet ) {
+        # Nokia N810 device
+        DEFINES += N810
+    }
+}
+
diff --git a/src/gui/about.ui b/src/gui/about.ui
new file mode 100644 (file)
index 0000000..28ceb88
--- /dev/null
@@ -0,0 +1,407 @@
+<ui version="4.0" >
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog" >
+  <property name="windowModality" >
+   <enum>Qt::WindowModal</enum>
+  </property>
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>487</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize" >
+   <size>
+    <width>77</width>
+    <height>77</height>
+   </size>
+  </property>
+  <property name="maximumSize" >
+   <size>
+    <width>500</width>
+    <height>1000</height>
+   </size>
+  </property>
+  <property name="palette" >
+   <palette>
+    <active>
+     <colorrole role="Base" >
+      <brush brushstyle="SolidPattern" >
+       <color alpha="255" >
+        <red>239</red>
+        <green>235</green>
+        <blue>231</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="AlternateBase" >
+      <brush brushstyle="SolidPattern" >
+       <color alpha="255" >
+        <red>239</red>
+        <green>235</green>
+        <blue>231</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </active>
+    <inactive>
+     <colorrole role="Base" >
+      <brush brushstyle="SolidPattern" >
+       <color alpha="255" >
+        <red>239</red>
+        <green>235</green>
+        <blue>231</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="AlternateBase" >
+      <brush brushstyle="SolidPattern" >
+       <color alpha="255" >
+        <red>239</red>
+        <green>235</green>
+        <blue>231</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </inactive>
+    <disabled>
+     <colorrole role="Base" >
+      <brush brushstyle="SolidPattern" >
+       <color alpha="255" >
+        <red>255</red>
+        <green>255</green>
+        <blue>255</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="AlternateBase" >
+      <brush brushstyle="SolidPattern" >
+       <color alpha="255" >
+        <red>239</red>
+        <green>235</green>
+        <blue>231</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </disabled>
+   </palette>
+  </property>
+  <property name="windowTitle" >
+   <string>About application</string>
+  </property>
+  <property name="locale" >
+   <locale country="AnyCountry" language="C" />
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" >
+    <layout class="QHBoxLayout" name="horizontalLayout" >
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout" >
+       <item>
+        <widget class="QLabel" name="FosdemIcon" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="maximumSize" >
+          <size>
+           <width>77</width>
+           <height>68</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+         <property name="pixmap" >
+          <pixmap resource="../icons.qrc" >:/icons/brain-alone.png</pixmap>
+         </property>
+         <property name="scaledContents" >
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer" >
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_2" >
+       <item>
+        <widget class="QScrollArea" name="scrollArea" >
+         <property name="widgetResizable" >
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents" >
+          <property name="geometry" >
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>389</width>
+            <height>429</height>
+           </rect>
+          </property>
+          <layout class="QGridLayout" name="gridLayout_2" >
+           <item row="0" column="0" >
+            <widget class="QWidget" native="1" name="content" >
+             <layout class="QVBoxLayout" name="verticalLayout_3" >
+              <item>
+               <widget class="QLabel" name="label" >
+                <property name="sizePolicy" >
+                 <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="font" >
+                 <font>
+                  <weight>75</weight>
+                  <bold>true</bold>
+                 </font>
+                </property>
+                <property name="text" >
+                 <string>FOSDEM Schedule</string>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QLabel" name="label_2" >
+                <property name="text" >
+                 <string>Version 0.3</string>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QLabel" name="spacer" >
+                <property name="text" >
+                 <string/>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QLabel" name="description" >
+                <property name="text" >
+                 <string>FOSDEM Schedule is an application written in Qt, which makes the conference schedule available offline. Supports searches on various items (speaker, speech topic, location, etc.). For Nokia N810 and N900 Internet Tablets.</string>
+                </property>
+                <property name="wordWrap" >
+                 <bool>true</bool>
+                </property>
+                <property name="openExternalLinks" >
+                 <bool>true</bool>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QLabel" name="label_3" >
+                <property name="text" >
+                 <string/>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QGroupBox" name="groupBox" >
+                <property name="sizePolicy" >
+                 <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="minimumSize" >
+                 <size>
+                  <width>0</width>
+                  <height>0</height>
+                 </size>
+                </property>
+                <property name="font" >
+                 <font>
+                  <weight>75</weight>
+                  <bold>true</bold>
+                 </font>
+                </property>
+                <property name="title" >
+                 <string>Developers</string>
+                </property>
+                <layout class="QVBoxLayout" name="verticalLayout_4" >
+                 <item>
+                  <widget class="QLabel" name="label_4" >
+                   <property name="sizePolicy" >
+                    <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="font" >
+                    <font>
+                     <weight>50</weight>
+                     <bold>false</bold>
+                    </font>
+                   </property>
+                   <property name="text" >
+                    <string>Berendova Monika, Hanzes Matus, Komara Martin, Korinek Pavol, Pavelka Pavol, Timko Marek, Uzak Matus, Fortes Francisco</string>
+                   </property>
+                   <property name="wordWrap" >
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </widget>
+              </item>
+              <item>
+               <widget class="QGroupBox" name="groupBox_2" >
+                <property name="sizePolicy" >
+                 <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="font" >
+                 <font>
+                  <weight>75</weight>
+                  <bold>true</bold>
+                 </font>
+                </property>
+                <property name="title" >
+                 <string>Notice</string>
+                </property>
+                <layout class="QVBoxLayout" name="verticalLayout_5" >
+                 <item>
+                  <widget class="QLabel" name="label_5" >
+                   <property name="sizePolicy" >
+                    <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="font" >
+                    <font>
+                     <weight>50</weight>
+                     <bold>false</bold>
+                    </font>
+                   </property>
+                   <property name="text" >
+                    <string>FOSDEM Schedule 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, or (at your option) any later version.</string>
+                   </property>
+                   <property name="wordWrap" >
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QLabel" name="label_6" >
+                   <property name="font" >
+                    <font>
+                     <weight>50</weight>
+                     <bold>false</bold>
+                    </font>
+                   </property>
+                   <property name="text" >
+                    <string>FOSDEM Schedule 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.</string>
+                   </property>
+                   <property name="wordWrap" >
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </widget>
+              </item>
+              <item>
+               <widget class="QLabel" name="copyright" >
+                <property name="text" >
+                 <string>Copyright (C) 2010 Ixonos Plc.</string>
+                </property>
+               </widget>
+              </item>
+             </layout>
+            </widget>
+           </item>
+           <item row="1" column="0" >
+            <spacer name="verticalSpacer_2" >
+             <property name="orientation" >
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0" >
+              <size>
+               <width>20</width>
+               <height>20</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_2" >
+         <item>
+          <spacer name="horizontalSpacer" >
+           <property name="orientation" >
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0" >
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QPushButton" name="okButton" >
+           <property name="text" >
+            <string>OK</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../icons.qrc" />
+ </resources>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>AboutDialog</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>512</x>
+     <y>724</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>282</x>
+     <y>375</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/gui/alarmdialog.cpp b/src/gui/alarmdialog.cpp
new file mode 100644 (file)
index 0000000..4891b11
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "alarmdialog.h"
+#include <conference.h>
+
+#include <QApplication>
+#include <alarm.h>
+#include <event.h>
+
+#include <QDir>
+#include <QProcess>
+
+const int SNOOZE_TIME = 5; // in minutes
+
+AlarmDialog::AlarmDialog(int argc, char *argv[], QWidget *aParent)
+    : QDialog(aParent)
+    , mEventId(0)
+    , mAlarmId(0)
+{
+    setupUi(this);
+
+    if(argc<3)
+    {
+        // not enough arguments passed to the dialog
+        // Usage: $ ./dialog eventId alarmId
+        // Example: $ ./dialog 521 13
+        //
+        // TODO: handle this case
+    }
+    else
+    {
+        mEventId = QString(argv[1]).toInt();
+        mAlarmId = QString(argv[2]).toInt();
+    }
+
+    connect(stopPB, SIGNAL(clicked()), SLOT(closeDialog()));
+    connect(appPB, SIGNAL(clicked()), SLOT(runApp()));
+    connect(snoozePB, SIGNAL(clicked()), SLOT(snooze()));
+
+    QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
+    database.setDatabaseName(QDir::homePath() + "/.fosdem/fosdem.sqlite");
+    database.open();
+
+    QString titleStr;
+    QString messageStr;
+    QString timeStr;
+    QString personsStr;
+    QString roomStr;
+    try
+    {
+        Event event = Event::getById(mEventId,Conference::activeConference());
+        titleStr = "Event alarm";
+        messageStr = event.title();
+        timeStr = event.start().toString("hh:mm") + "-" + event.start().addSecs(event.duration()).toString("hh:mm");
+        personsStr = event.persons().join(" and ");
+        roomStr = event.room();
+    }
+    catch(OrmNoObjectException&)
+    {
+        titleStr = QString("ERROR");
+        messageStr = QString("No such event in the DB: %1").arg(QString::number(mEventId));
+    }
+    catch(...) {} // TODO: implement
+    message->setText(messageStr);
+    setWindowTitle(titleStr);
+    time->setText(timeStr);
+    persons->setText(personsStr);
+    room->setText(roomStr);
+}
+
+void AlarmDialog::runApp()
+{
+    QString program = QDir::currentPath() + "/" + *qApp->argv();
+    QProcess::startDetached(program,QStringList()<<QString::number(mEventId));
+    closeDialog();
+}
+
+void AlarmDialog::snooze()
+{
+    if(mEventId==0) // not valid event ID
+        return;
+
+    Alarm alarm;
+    alarm.addAlarm(mEventId,QDateTime::currentDateTime().addSecs(60*SNOOZE_TIME));
+    qApp->quit();
+}
+
+void AlarmDialog::closeDialog()
+{
+    // before closing the dialog, it is necessary to remove alarm flag from the DB
+    try
+    {
+        Event event = Event::getById(mEventId,Conference::activeConference());
+        event.setHasAlarm(false);
+        event.update("alarm");
+    }
+    catch(OrmNoObjectException &) {} // TODO: implement
+    catch(...) {} // just close dialog
+    qApp->quit();
+}
+
diff --git a/src/gui/alarmdialog.h b/src/gui/alarmdialog.h
new file mode 100644 (file)
index 0000000..230ff89
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef ALARMDIALOG_H
+#define ALARMDIALOG_H
+
+#include <QDialog>
+#include "ui_alarmdialog.h"
+
+class AlarmDialog : public QDialog, Ui::AlarmDialog
+{
+    Q_OBJECT
+    public:
+        AlarmDialog(int argc, char *argv[], QWidget *aParent = NULL);
+        ~AlarmDialog() {}
+    private slots:
+        void runApp();
+        void snooze();
+        void closeDialog();
+    private:
+        int mEventId; // event ID obtained from 'schedule'
+        int mAlarmId; // cookie assigned by alarmd
+};
+
+#endif /* ALARMDIALOG_H */
+
diff --git a/src/gui/alarmdialog.ui b/src/gui/alarmdialog.ui
new file mode 100644 (file)
index 0000000..d0bd806
--- /dev/null
@@ -0,0 +1,160 @@
+<ui version="4.0" >
+ <class>AlarmDialog</class>
+ <widget class="QDialog" name="AlarmDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>406</width>
+    <height>176</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="2" column="0" >
+    <layout class="QVBoxLayout" name="verticalLayout" >
+     <item>
+      <widget class="QLabel" name="message" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text" >
+        <string>Alarm message goes here</string>
+       </property>
+       <property name="wordWrap" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_2" >
+       <item>
+        <widget class="QLabel" name="label" >
+         <property name="text" >
+          <string/>
+         </property>
+         <property name="pixmap" >
+          <pixmap resource="../icons.qrc" >:/icons/fosdem.png</pixmap>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QGridLayout" name="gridLayout_2" >
+         <item row="0" column="1" >
+          <widget class="QLabel" name="label_2" >
+           <property name="text" >
+            <string>Time:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1" >
+          <widget class="QLabel" name="label_3" >
+           <property name="text" >
+            <string>Presenter(s):</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1" >
+          <widget class="QLabel" name="label_4" >
+           <property name="text" >
+            <string>Room:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="3" >
+          <widget class="QLabel" name="persons" >
+           <property name="text" >
+            <string>PRESETNER(S)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="3" >
+          <widget class="QLabel" name="time" >
+           <property name="text" >
+            <string>TIME</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="3" >
+          <widget class="QLabel" name="room" >
+           <property name="text" >
+            <string>ROOM</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0" >
+          <widget class="QLabel" name="label_5" >
+           <property name="text" >
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2" >
+          <widget class="QLabel" name="label_6" >
+           <property name="text" >
+            <string/>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer" >
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout" >
+       <item>
+        <widget class="QPushButton" name="appPB" >
+         <property name="text" >
+          <string>App</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="snoozePB" >
+         <property name="text" >
+          <string>Snooze</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="stopPB" >
+         <property name="text" >
+          <string>Cancel</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../icons.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/conflictdialogcontainer.cpp b/src/gui/conflictdialogcontainer.cpp
new file mode 100644 (file)
index 0000000..35e69f2
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "conflictdialogcontainer.h"
+
+ConflictDialogContainer::ConflictDialogContainer(QWidget *aParent)
+    : TabContainer( aParent )
+{
+}
+
+void ConflictDialogContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    Q_UNUSED(aDate);
+
+    static_cast<EventModel*>(treeView->model())->loadConflictEvents( mEventId, aConferenceId );
+    dayNavigator->hide();
+}
+
+void ConflictDialogContainer::updateTreeView(const QDate &aDate)
+{
+    TabContainer::updateTreeView(aDate);
+    treeView->setAllExpanded(true);
+}
+
diff --git a/src/gui/conflictdialogcontainer.h b/src/gui/conflictdialogcontainer.h
new file mode 100644 (file)
index 0000000..de5574e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CONFLICTDIALOGCONTAINER_H
+#define CONFLICTDIALOGCONTAINER_H
+
+#include "tabcontainer.h"
+
+class ConflictDialogContainer: public TabContainer
+{
+    Q_OBJECT
+public:
+    ConflictDialogContainer(QWidget *aParent);
+    virtual ~ConflictDialogContainer(){}
+
+    void setEventId(int aEventId) { mEventId = aEventId; }
+
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId );
+
+protected slots:
+    virtual void updateTreeView(const QDate &aDate);
+
+private:
+    int mEventId;
+};
+
+#endif /* CONFLICTDIALOGCONTAINER_H */
+
diff --git a/src/gui/conflictsdialog.cpp b/src/gui/conflictsdialog.cpp
new file mode 100644 (file)
index 0000000..cde9a4a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "conflictsdialog.h"
+
+ConflictsDialog::ConflictsDialog(int aEventId, QWidget *aParent)
+    : QDialog(aParent)
+{
+    setupUi(this);
+    connect(container, SIGNAL(eventHasChanged(int,bool)), this, SIGNAL(eventHasChanged(int,bool)));
+    connect(container, SIGNAL(eventHasChanged(int,bool)), container, SLOT(updateTreeViewModel(int,bool)));
+
+    container->setEventId(aEventId);
+
+    int confId = Conference::activeConference();
+    QDate startDate = Conference::getById(confId).start();
+    QDate endDate = Conference::getById(confId).end();
+    container->setDates(startDate, endDate);
+}
+
+ConflictsDialog::~ConflictsDialog()
+{
+    disconnect(container, SIGNAL(eventHasChanged(int,bool)), this, SIGNAL(eventHasChanged(int,bool)));
+}
+
diff --git a/src/gui/conflictsdialog.h b/src/gui/conflictsdialog.h
new file mode 100644 (file)
index 0000000..c9ac58b
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef CONFLICTSDIALOG_H
+#define CONFLICTSDIALOG_H
+
+#include "ui_conflictsdialog.h"
+#include <QDialog>
+
+class ConflictsDialog : public QDialog, Ui::ConflictsDialog
+{
+    Q_OBJECT
+public:
+    ConflictsDialog(int aEventId, QWidget *aParent = NULL);
+    ~ConflictsDialog();
+signals:
+    void eventHasChanged(int aEventId, bool aReloadModel = false);
+};
+
+#endif /* CONFLICTSDIALOG_H */ 
+
diff --git a/src/gui/conflictsdialog.ui b/src/gui/conflictsdialog.ui
new file mode 100644 (file)
index 0000000..fd1de1a
--- /dev/null
@@ -0,0 +1,89 @@
+<ui version="4.0" >
+ <class>ConflictsDialog</class>
+ <widget class="QDialog" name="ConflictsDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>471</width>
+    <height>373</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" >
+   <item>
+    <widget class="QLabel" name="message" >
+     <property name="text" >
+      <string>Selected Event is in conflict with the following event(s):</string>
+     </property>
+     <property name="wordWrap" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="ConflictDialogContainer" native="1" name="container" >
+     <property name="sizePolicy" >
+      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+       <horstretch>0</horstretch>
+       <verstretch>1</verstretch>
+      </sizepolicy>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" >
+     <item>
+      <spacer name="horizontalSpacer" >
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="okButton" >
+       <property name="text" >
+        <string>OK</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ConflictDialogContainer</class>
+   <extends>QWidget</extends>
+   <header>conflictdialogcontainer.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>ConflictsDialog</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>301</x>
+     <y>156</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>175</x>
+     <y>89</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/gui/daynavigatorwidget.cpp b/src/gui/daynavigatorwidget.cpp
new file mode 100644 (file)
index 0000000..0672f35
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "daynavigatorwidget.h"
+
+#include <QPainter>
+#include <QFontMetrics>
+#include <QLabel>
+
+#include <QDebug>
+
+DayNavigatorWidget::DayNavigatorWidget(QWidget *aParent)
+    : QWidget(aParent)
+    , mStartDate(QDate())
+    , mEndDate(QDate())
+    , mCurDate(QDate())
+{
+    setupUi(this);
+    connect(prevDayButton, SIGNAL(clicked()), SLOT(prevDayButtonClicked()));
+    connect(nextDayButton, SIGNAL(clicked()), SLOT(nextDayButtonClicked()));
+
+    mFontMetrics = new QFontMetrics(QLabel().font());
+}
+
+void DayNavigatorWidget::setDates(const QDate &aStartDate, const QDate &aEndDate)
+{
+    Q_ASSERT(aStartDate<=aEndDate);
+
+    //qDebug() << "DayNavigatorWidget::setDates(): " << aStartDate << ", " << aEndDate;
+    mStartDate = aStartDate;
+    mEndDate = aEndDate;
+    mCurDate = aStartDate;
+
+    QRect rect = mFontMetrics->boundingRect(mCurDate.toString("MMM dd yyyy"));
+
+    if(mStartDate==mEndDate) // only one day conference
+    {
+        prevDayButton->setDisabled(true);
+        nextDayButton->setDisabled(true);
+        emit(dateChanged(mCurDate));
+    }
+    else
+    {
+        // at least 2-days conference
+        prevDayButton->setDisabled(true);
+        nextDayButton->setDisabled(false);
+        emit(dateChanged(mCurDate));
+    }
+}
+
+void DayNavigatorWidget::prevDayButtonClicked()
+{
+    //qDebug() << mStartDate << ":" << mCurDate << ":" << mEndDate;
+    if(mCurDate>mStartDate)
+    {
+        mCurDate = mCurDate.addDays(-1);
+        // check start date
+        if(mCurDate==mStartDate || mStartDate==mEndDate)
+            prevDayButton->setDisabled(true);
+        else
+            prevDayButton->setDisabled(false);
+        // check end date
+        if(mCurDate==mEndDate || mStartDate==mEndDate)
+            nextDayButton->setDisabled(true);
+        else
+            nextDayButton->setDisabled(false);
+
+        emit(dateChanged(mCurDate));
+        selectedDate->update();
+    }
+}
+
+void DayNavigatorWidget::nextDayButtonClicked()
+{
+    //qDebug() << mStartDate << ":" << mCurDate << ":" << mEndDate;
+    if(mCurDate<mEndDate)
+    {
+        mCurDate = mCurDate.addDays(1);
+        // check start date
+        if(mCurDate==mStartDate || mStartDate==mEndDate)
+            prevDayButton->setDisabled(true);
+        else
+            prevDayButton->setDisabled(false);
+        // check end date
+        if(mCurDate==mEndDate || mStartDate==mEndDate)
+            nextDayButton->setDisabled(true);
+        else
+            nextDayButton->setDisabled(false);
+
+        emit(dateChanged(mCurDate));
+        selectedDate->update();
+    }
+}
+
+void DayNavigatorWidget::paintEvent(QPaintEvent *aEvent)
+{
+    Q_UNUSED(aEvent);
+
+    QString selectedDateStr = mCurDate.toString("MMM dd yyyy");
+
+    QPainter painter(this);
+    painter.save();
+    QRect r = selectedDate->geometry();
+    QRect s = mFontMetrics->boundingRect(selectedDateStr);
+    QPoint p = QPoint(
+            r.x() + r.width()/2 - s.height()/2 - mFontMetrics->descent(),
+            - 130
+            );
+
+    painter.translate(r.width()/2, r.height()/2);
+    painter.rotate(270);
+    painter.drawText(p.y(), p.x(), selectedDateStr); // y,x,string
+    painter.restore();
+}
+
diff --git a/src/gui/daynavigatorwidget.h b/src/gui/daynavigatorwidget.h
new file mode 100644 (file)
index 0000000..f39fcce
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef DAYNAVIGATORWIDGET_H
+#define DAYNAVIGATORWIDGET_H
+
+#include "ui_daynavigatorwidget.h"
+#include <QObject>
+#include <QDate>
+
+/*#include <QPainter>*/
+/*#include <QLabel>*/
+
+/*class QFontMetrics;*/
+
+/*class VerticalLabel : public QWidget*/
+/*{*/
+
+/*public:*/
+/*VerticalLabel(QWidget *aParent = NULL)*/
+/*: QWidget(aParent)*/
+/*, mText("")*/
+/*{*/
+/*mFont = QLabel().font();*/
+/*}   */
+
+/*void paintEvent(QPaintEvent *)*/
+/*{   */
+/*QPainter p(this);*/
+/*drawRotatedText(&p, 270, width()/2, height()/2, mText);*/
+/*}   */
+
+/*void drawRotatedText(QPainter *aPainter, qreal aDegrees, int x, int y, const QString &aText)*/
+/*{   */
+
+/*aPainter->save();*/
+/*aPainter->setFont(mFont);*/
+/*aPainter->translate(x, y); */
+/*aPainter->rotate(aDegrees);*/
+/*QFontMetrics fm(mFont);*/
+/*QRect r = fm.boundingRect(aText);*/
+/*aPainter->drawText(-r.width()/2, fm.descent()/2, aText);*/
+/*aPainter->restore();*/
+/*}   */
+
+/*void setText(const QString &aText)*/
+/*{*/
+/*mText = aText;*/
+/*update();*/
+/*}*/
+
+/*private:*/
+/*QString mText;*/
+/*QFont mFont;*/
+/*};*/
+
+class DayNavigatorWidget : public QWidget, private Ui::DayNavigatorWidget
+{
+    Q_OBJECT
+    public:
+        DayNavigatorWidget(QWidget *aParent = NULL);
+        ~DayNavigatorWidget() {}
+        void setDates(const QDate &aStartDate, const QDate &aEndDate);
+    protected:
+        void paintEvent(QPaintEvent *);
+    private slots:
+        void prevDayButtonClicked();
+        void nextDayButtonClicked();
+    signals:
+        void dateChanged(const QDate &aDate);
+    private:
+        QDate mStartDate;
+        QDate mEndDate;
+        QDate mCurDate;
+        QFontMetrics *mFontMetrics;
+};
+
+#endif /* DAYNAVIGATORWIDGET_H */
+
diff --git a/src/gui/daynavigatorwidget.ui b/src/gui/daynavigatorwidget.ui
new file mode 100644 (file)
index 0000000..c5eae24
--- /dev/null
@@ -0,0 +1,73 @@
+<ui version="4.0" >
+ <class>DayNavigatorWidget</class>
+ <widget class="QWidget" name="DayNavigatorWidget" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>52</width>
+    <height>198</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="Expanding" hsizetype="Minimum" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle" >
+   <string>Form</string>
+  </property>
+  <property name="layoutDirection" >
+   <enum>Qt::LeftToRight</enum>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="1" column="0" >
+    <layout class="QVBoxLayout" name="verticalLayout" >
+     <item>
+      <widget class="QToolButton" name="nextDayButton" >
+       <property name="text" >
+        <string>...</string>
+       </property>
+       <property name="autoRaise" >
+        <bool>true</bool>
+       </property>
+       <property name="arrowType" >
+        <enum>Qt::UpArrow</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QWidget" native="1" name="selectedDate" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Expanding" hsizetype="Minimum" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="prevDayButton" >
+       <property name="text" >
+        <string>...</string>
+       </property>
+       <property name="autoRaise" >
+        <bool>true</bool>
+       </property>
+       <property name="arrowType" >
+        <enum>Qt::DownArrow</enum>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <slots>
+  <slot>prevDayButtonClicked()</slot>
+  <slot>nextDayButtonClicked()</slot>
+ </slots>
+</ui>
diff --git a/src/gui/dayviewtabcontainer.cpp b/src/gui/dayviewtabcontainer.cpp
new file mode 100644 (file)
index 0000000..4d5152b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dayviewtabcontainer.h"
+
+DayViewTabContainer::DayViewTabContainer(QWidget *aParent) : TabContainer( aParent )
+{
+}
+
+DayViewTabContainer::~DayViewTabContainer()
+{
+}
+
+void DayViewTabContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    static_cast<EventModel*>(treeView->model())->loadEvents( aDate, aConferenceId );
+}
diff --git a/src/gui/dayviewtabcontainer.h b/src/gui/dayviewtabcontainer.h
new file mode 100644 (file)
index 0000000..932d970
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAYVIEWTABCONTAINER_H_
+#define DAYVIEWTABCONTAINER_H_
+
+#include "tabcontainer.h"
+
+class DayViewTabContainer: public TabContainer {
+    Q_OBJECT
+public:
+    DayViewTabContainer(QWidget *aParent);
+    virtual ~DayViewTabContainer();
+protected:
+    virtual void loadEvents(const QDate &aDate, const int aConferenceId );
+};
+
+#endif /* DAYVIEWTABCONTAINER_H_ */
diff --git a/src/gui/eventdialog.cpp b/src/gui/eventdialog.cpp
new file mode 100644 (file)
index 0000000..91f3a61
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "eventdialog.h"
+#include <conference.h>
+
+#include <QScrollBar>
+
+#ifdef MAEMO
+#include <alarm.h>
+#endif
+
+EventDialog::EventDialog(const int &aEventId, QWidget *aParent)
+    : QDialog(aParent)
+    , mEventId(aEventId)
+{
+    setupUi(this);
+
+#ifdef MAEMO
+    showFullScreen();
+#else
+    alarmButton->hide();
+#endif
+
+    Event event = Event::getById(mEventId,Conference::activeConference());
+
+    title->setText(event.title());
+    persons->setText(event.persons().join(" and "));
+    abstract->setText(event.abstract());
+    description->setText(event.description());
+    links->setText(static_cast<QStringList>(event.links().values()).join("\n"));
+
+    connect(favouriteButton, SIGNAL(clicked()), SLOT(favouriteClicked()));
+    connect(alarmButton, SIGNAL(clicked()), SLOT(alarmClicked()));
+
+    if(event.isFavourite())
+    {
+        favouriteButton->setIcon(QIcon(":/icons/favourite-onBig.png"));
+    }
+
+    if(event.hasAlarm())
+    {
+        alarmButton->setIcon(QIcon(":/icons/alarm-onBig.png"));
+    }
+}
+
+void EventDialog::favouriteClicked()
+{
+    Event event = Event::getById(mEventId,Conference::activeConference());
+
+    QList<Event> conflicts = Event::conflictEvents(event.id(),Conference::activeConference());
+    if(event.isFavourite())
+    {
+        event.setFavourite(false);
+        favouriteButton->setIcon(QIcon(":/icons/favourite-offBig.png"));
+    }
+    else
+    {
+        event.setFavourite(true);
+        favouriteButton->setIcon(QIcon(":/icons/favourite-onBig.png"));
+    }
+    event.update("favourite");
+
+    if(event.isFavourite())
+    {
+        // event has became 'favourite' and so 'conflicts' list may have changed
+        conflicts = Event::conflictEvents(event.id(),Conference::activeConference());
+    }
+
+    qDebug() << " FAVOURITE [" << event.id() << "] -> " << event.isFavourite();
+
+    // have to emit 'eventHasChanged' signal on all events in conflict
+    for(int i=0; i<conflicts.count(); i++)
+        emit(eventHasChanged(conflicts[i].id()));
+
+    // since the Favourite icon has changed, update TreeViews accordingly
+    // all TreeViews have to listen on this signal
+    emit(eventHasChanged(event.id(),true));
+}
+
+void EventDialog::alarmClicked()
+{
+    Event event = Event::getById(mEventId,Conference::activeConference());
+
+    if(event.hasAlarm())
+    {
+        event.setHasAlarm(false); // update DB
+        alarmButton->setIcon(QIcon(":/icons/alarm-offBig.png"));
+#ifdef MAEMO
+        // remove alarm from the 'alarmd' alrms list
+        Alarm alarm;
+        alarm.deleteAlarm(event.id());
+        // TODO: test if removing was successfull
+#endif /* MAEMO */
+    }
+    else
+    {
+        event.setHasAlarm(true);
+        alarmButton->setIcon(QIcon(":/icons/alarm-onBig.png"));
+#ifdef MAEMO
+        // add alarm to the 'alarmd'
+        Alarm alarm;
+        int cookie = alarm.addAlarm(event.id(),QDateTime::currentDateTime().addSecs(10));
+        qDebug() << "cookie: " << cookie;
+#endif /* MAEMO */
+    }
+    event.update("alarm");
+    qDebug() << " ALARM [" << event.id() << "] -> " << event.hasAlarm();
+    // since the Alarm icon has changed, update TreeView accordingly
+    // all TreeViews have to listen on this signal
+    emit(eventHasChanged(event.id()));
+}
+
diff --git a/src/gui/eventdialog.h b/src/gui/eventdialog.h
new file mode 100644 (file)
index 0000000..3613230
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef EVENTDIALOG_H
+#define EVENTDIALOG_H
+
+#include <QDialog>
+#include "ui_eventdialog.h"
+#include <event.h>
+
+class EventDialog : public QDialog, Ui::EventDialog
+{ 
+    Q_OBJECT
+public:
+    EventDialog(const int &aEventId, QWidget *aParent = NULL);
+    ~EventDialog() {}
+private slots:
+    void favouriteClicked();
+    void alarmClicked();
+signals:
+    void eventHasChanged(int aEventId, bool aReloadModel = false); // emited when user changes some event details, eg. sets it Favourite
+private:
+    int mEventId;
+};
+
+#endif /* EVENTDIALOG_H */
+
diff --git a/src/gui/eventdialog.ui b/src/gui/eventdialog.ui
new file mode 100644 (file)
index 0000000..2a3de35
--- /dev/null
@@ -0,0 +1,337 @@
+<ui version="4.0" >
+ <class>EventDialog</class>
+ <widget class="QDialog" name="EventDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>485</width>
+    <height>352</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle" >
+   <string>Details</string>
+  </property>
+  <property name="autoFillBackground" >
+   <bool>false</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" >
+    <layout class="QVBoxLayout" name="verticalLayout" >
+     <item>
+      <widget class="QLabel" name="title" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="font" >
+        <font>
+         <weight>75</weight>
+         <bold>true</bold>
+         <underline>true</underline>
+        </font>
+       </property>
+       <property name="text" >
+        <string>Title goes here</string>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignCenter</set>
+       </property>
+       <property name="wordWrap" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QScrollArea" name="scrollArea" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="widgetResizable" >
+        <bool>true</bool>
+       </property>
+       <widget class="QWidget" name="scrollAreaWidgetContents" >
+        <property name="geometry" >
+         <rect>
+          <x>0</x>
+          <y>0</y>
+          <width>461</width>
+          <height>254</height>
+         </rect>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_2" >
+         <item row="0" column="0" >
+          <widget class="QWidget" native="1" name="content" >
+           <property name="sizePolicy" >
+            <sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <layout class="QVBoxLayout" name="verticalLayout_2" >
+            <item>
+             <widget class="QGroupBox" name="personsGB" >
+              <property name="sizePolicy" >
+               <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="font" >
+               <font>
+                <weight>75</weight>
+                <bold>true</bold>
+               </font>
+              </property>
+              <property name="title" >
+               <string>Persons</string>
+              </property>
+              <layout class="QVBoxLayout" name="verticalLayout_3" >
+               <item>
+                <widget class="QLabel" name="persons" >
+                 <property name="font" >
+                  <font>
+                   <weight>50</weight>
+                   <bold>false</bold>
+                  </font>
+                 </property>
+                 <property name="text" >
+                  <string>PERSONS</string>
+                 </property>
+                 <property name="wordWrap" >
+                  <bool>true</bool>
+                 </property>
+                 <property name="openExternalLinks" >
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+            <item>
+             <widget class="QGroupBox" name="abstractGB" >
+              <property name="sizePolicy" >
+               <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="font" >
+               <font>
+                <weight>75</weight>
+                <bold>true</bold>
+               </font>
+              </property>
+              <property name="title" >
+               <string>Abstract</string>
+              </property>
+              <layout class="QVBoxLayout" name="verticalLayout_4" >
+               <item>
+                <widget class="QLabel" name="abstract" >
+                 <property name="font" >
+                  <font>
+                   <weight>50</weight>
+                   <bold>false</bold>
+                  </font>
+                 </property>
+                 <property name="text" >
+                  <string>ABSTRACT</string>
+                 </property>
+                 <property name="wordWrap" >
+                  <bool>true</bool>
+                 </property>
+                 <property name="openExternalLinks" >
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+            <item>
+             <widget class="QGroupBox" name="descriptionGB" >
+              <property name="font" >
+               <font>
+                <weight>75</weight>
+                <bold>true</bold>
+               </font>
+              </property>
+              <property name="title" >
+               <string>Description</string>
+              </property>
+              <layout class="QVBoxLayout" name="verticalLayout_5" >
+               <item>
+                <widget class="QLabel" name="description" >
+                 <property name="sizePolicy" >
+                  <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="font" >
+                  <font>
+                   <weight>50</weight>
+                   <bold>false</bold>
+                  </font>
+                 </property>
+                 <property name="text" >
+                  <string>DESCRIPTION</string>
+                 </property>
+                 <property name="wordWrap" >
+                  <bool>true</bool>
+                 </property>
+                 <property name="openExternalLinks" >
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+            <item>
+             <widget class="QGroupBox" name="linksGB" >
+              <property name="font" >
+               <font>
+                <weight>75</weight>
+                <bold>true</bold>
+               </font>
+              </property>
+              <property name="title" >
+               <string>Links</string>
+              </property>
+              <layout class="QVBoxLayout" name="verticalLayout_6" >
+               <item>
+                <widget class="QLabel" name="links" >
+                 <property name="sizePolicy" >
+                  <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="font" >
+                  <font>
+                   <weight>50</weight>
+                   <bold>false</bold>
+                  </font>
+                 </property>
+                 <property name="text" >
+                  <string>LINKS</string>
+                 </property>
+                 <property name="wordWrap" >
+                  <bool>true</bool>
+                 </property>
+                 <property name="openExternalLinks" >
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
+           </layout>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </widget>
+     </item>
+     <item>
+      <spacer name="verticalSpacer_2" >
+       <property name="orientation" >
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeType" >
+        <enum>QSizePolicy::Minimum</enum>
+       </property>
+       <property name="sizeHint" stdset="0" >
+        <size>
+         <width>20</width>
+         <height>10</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout" >
+       <item>
+        <widget class="QToolButton" name="alarmButton" >
+         <property name="text" >
+          <string>...</string>
+         </property>
+         <property name="icon" >
+          <iconset resource="../icons.qrc" >
+           <normaloff>:/icons/alarm-offBig.png</normaloff>:/icons/alarm-offBig.png</iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="favouriteButton" >
+         <property name="text" >
+          <string>...</string>
+         </property>
+         <property name="icon" >
+          <iconset resource="../icons.qrc" >
+           <normaloff>:/icons/favourite-offBig.png</normaloff>:/icons/favourite-offBig.png</iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer" >
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="okButton" >
+         <property name="text" >
+          <string>OK</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../icons.qrc" />
+ </resources>
+ <connections>
+  <connection>
+   <sender>okButton</sender>
+   <signal>clicked()</signal>
+   <receiver>EventDialog</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>287</x>
+     <y>84</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>169</x>
+     <y>53</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/gui/favtabcontainer.cpp b/src/gui/favtabcontainer.cpp
new file mode 100644 (file)
index 0000000..3f1c0e3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "favtabcontainer.h"
+
+FavTabContainer::FavTabContainer(QWidget *aParent) : TabContainer( aParent )
+{
+}
+
+void FavTabContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    static_cast<EventModel*>(treeView->model())->loadFavEvents( aDate, aConferenceId );
+}
+
diff --git a/src/gui/favtabcontainer.h b/src/gui/favtabcontainer.h
new file mode 100644 (file)
index 0000000..e4243f5
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FAVTABCONTAINER_H_
+#define FAVTABCONTAINER_H_
+
+#include "tabcontainer.h"
+
+class FavTabContainer: public TabContainer
+{
+    Q_OBJECT
+public:
+    FavTabContainer(QWidget *aParent);
+    virtual ~FavTabContainer(){}
+
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId );
+};
+
+#endif /* FAVTABCONTAINER_H_ */
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
new file mode 100644 (file)
index 0000000..6a4cbed
--- /dev/null
@@ -0,0 +1,90 @@
+include(../global.pri)
+TEMPLATE = lib
+TARGET = gui
+DESTDIR = ../bin
+CONFIG += static
+QT += sql \
+    xml \
+    network
+
+# module dependencies
+LIBS += -L$$DESTDIR \
+    -lmvc \
+    -lorm \
+    -lsql
+INCLUDEPATH += ../orm \
+    ../mvc \
+    ../sql \
+    ../app
+DEPENDPATH += . \
+    ../orm \
+    ../mvc \
+    ../sql
+TARGETDEPS += $$DESTDIR/liborm.a \
+    $$DESTDIR/libmvc.a \
+    $$DESTDIR/libsql.a
+maemo { 
+    LIBS += -L$$DESTDIR \
+        -lqalarm
+    INCLUDEPATH += ../alarm
+    DEPENDPATH += ../alarm
+    TARGETDEPS += $$DESTDIR/libqalarm.a
+}
+
+# A shamelessly long list of sources, headers and forms.
+# Please note that resources MUST be added to the app module
+# (which means they need to be added to the test module as well,
+# but I am sure you can live with that for the time being).
+
+FORMS += searchhead.ui \
+    mainwindow.ui \
+    daynavigatorwidget.ui \
+    importschedulewidget.ui \
+    about.ui \
+    eventdialog.ui \
+    conflictsdialog.ui \
+    tabcontainer.ui \
+    mapwindow.ui \
+    proxysettingsdialog.ui
+
+HEADERS += roomstabcontainer.h \
+    nowtabcontainer.h \
+    trackstabcontainer.h \
+    favtabcontainer.h \
+    searchtabcontainer.h \
+    searchhead.h \
+    dayviewtabcontainer.h \
+    conflictdialogcontainer.h \
+    conflictsdialog.h \
+    mainwindow.h \
+    daynavigatorwidget.h \
+    importschedulewidget.h \
+    eventdialog.h \
+    tabwidget.h \
+    tabcontainer.h \
+    mapwindow.h \
+    proxysettingsdialog.h
+
+SOURCES += roomstabcontainer.cpp \
+    nowtabcontainer.cpp \
+    trackstabcontainer.cpp \
+    favtabcontainer.cpp \
+    searchtabcontainer.cpp \
+    searchhead.cpp \
+    dayviewtabcontainer.cpp \
+    conflictdialogcontainer.cpp \
+    conflictsdialog.cpp \
+    mainwindow.cpp \
+    daynavigatorwidget.cpp \
+    importschedulewidget.cpp \
+    eventdialog.cpp \
+    tabwidget.cpp \
+    tabcontainer.cpp \
+    mapwindow.cpp \
+    proxysettingsdialog.cpp
+
+#maemo { 
+#    FORMS += alarmdialog.ui
+#    HEADERS += alarmdialog.h
+#    SOURCES += alarmdialog.cpp
+#}
diff --git a/src/gui/importschedulewidget.cpp b/src/gui/importschedulewidget.cpp
new file mode 100644 (file)
index 0000000..04c606b
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "importschedulewidget.h"
+
+#include <schedulexmlparser.h>
+#include "proxysettingsdialog.h"
+
+#include <QDir>
+#include <QFile>
+#include <QFileDialog>
+#include <QNetworkProxy>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QDebug>
+#include <appsettings.h>
+
+const QString SCHEDULE_URL = "http://fosdem.org/2010/schedule/xml";
+
+const QString PROXY_USERNAME;
+const QString PROXY_PASSWD;
+
+ImportScheduleWidget::ImportScheduleWidget(QWidget *aParent)
+    : QWidget(aParent)
+{
+    setupUi(this);
+
+    mXmlParser = new ScheduleXmlParser(this);
+    connect(mXmlParser, SIGNAL(progressStatus(int)), SLOT(showParsingProgress(int)));
+    connect(mXmlParser, SIGNAL(parsingSchedule(const QString &)), SLOT(parsingSchedule(const QString &)));
+
+    connect(browse, SIGNAL(clicked()), SLOT(browseSchedule()));
+    progressBar->hide();
+
+    cancel->hide();
+    importAction->hide();
+    connect(online, SIGNAL(clicked()), SLOT(downloadSchedule()));
+
+    connect(proxySettings, SIGNAL(clicked()), SLOT(setupProxy()));
+    mNetworkAccessManager = new QNetworkAccessManager(this);
+    connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkQueryFinished(QNetworkReply*)));
+    mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
+}
+
+ImportScheduleWidget::~ImportScheduleWidget()
+{
+    if(mXmlParser)
+    {
+        delete mXmlParser;
+        mXmlParser = NULL;
+    }
+    if(mNetworkAccessManager)
+    {
+        delete mNetworkAccessManager;
+        mNetworkAccessManager = NULL;
+    }
+}
+
+void ImportScheduleWidget::parsingSchedule(const QString &aTitle)
+{
+    importScheduleLabel->setText("Importing: " + aTitle);
+}
+
+void ImportScheduleWidget::showParsingProgress(int progress)
+{
+    progressBar->setValue(progress);
+}
+
+void ImportScheduleWidget::browseSchedule()
+{
+    QString scheduleFileName = QFileDialog::getOpenFileName(this, tr("Select Conference Schedule"), QDir::homePath(), tr("Schedule Files (*.xml)"));
+    if(QFile::exists(scheduleFileName))
+    {
+        QFile file(scheduleFileName);
+        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+        {
+            qDebug() << "can't open " << file.fileName();
+            return;
+        }
+
+        importData(file.readAll());
+
+    }
+    else
+    {
+        progressBar->hide();
+    }
+}
+
+void ImportScheduleWidget::networkQueryFinished(QNetworkReply *aReply)
+{
+    if ( aReply->error() != QNetworkReply::NoError )
+    {
+        qDebug() << "Error occured during download: " << aReply->errorString();
+    }
+    else
+    {
+        importData(aReply->readAll());
+    }
+}
+
+void ImportScheduleWidget::downloadSchedule()
+{
+    QNetworkRequest request;
+    request.setUrl(QUrl(SCHEDULE_URL));
+    mNetworkAccessManager->get(request);
+}
+
+void ImportScheduleWidget::importData(const QByteArray &aData)
+{
+    browse->hide();
+    online->hide();
+    progressBar->show();
+    proxySettings->hide();
+
+    int confId = mXmlParser->parseData(aData);
+
+    progressBar->hide();
+    browse->show();
+    online->show();
+    proxySettings->show();
+    importScheduleLabel->setText("Import schedule: ");
+
+    emit(scheduleImported(confId));
+}
+
+void ImportScheduleWidget::setupProxy()
+{
+    ProxySettingsDialog dialog;
+    dialog.exec();
+
+    qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
+    QNetworkProxy proxy(
+            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
+            AppSettings::proxyAddress(),
+            AppSettings::proxyPort(),
+            PROXY_USERNAME,
+            PROXY_PASSWD);
+    QNetworkProxy::setApplicationProxy(proxy);
+
+    mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
+}
+
diff --git a/src/gui/importschedulewidget.h b/src/gui/importschedulewidget.h
new file mode 100644 (file)
index 0000000..2fb8545
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef IMPORTSCHEDULEWIDGET_H
+#define IMPORTSCHEDULEWIDGET_H
+
+#include <QWidget>
+#include "ui_importschedulewidget.h"
+
+class ScheduleXmlParser;
+class QNetworkAccessManager;
+class QNetworkReply;
+
+class ImportScheduleWidget : public QWidget, Ui::ImportScheduleWidget
+{
+    Q_OBJECT
+    public:
+        ImportScheduleWidget(QWidget *aParent = NULL);
+        ~ImportScheduleWidget();
+    private slots:
+        void browseSchedule();
+        void parsingSchedule(const QString &aTitle);
+        void showParsingProgress(int progress);
+        void networkQueryFinished(QNetworkReply *aReply);
+        void downloadSchedule();
+        void setupProxy();
+    signals:
+        void scheduleImported(int confId);
+    private:
+        void importData(const QByteArray &aData);
+    private:
+        ScheduleXmlParser *mXmlParser;
+        QNetworkAccessManager *mNetworkAccessManager;
+};
+
+#endif /* IMPORTSCHEDULEWIDGET_H */
+
diff --git a/src/gui/importschedulewidget.ui b/src/gui/importschedulewidget.ui
new file mode 100644 (file)
index 0000000..4c76ed2
--- /dev/null
@@ -0,0 +1,128 @@
+<ui version="4.0" >
+ <class>ImportScheduleWidget</class>
+ <widget class="QWidget" name="ImportScheduleWidget" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>671</width>
+    <height>66</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle" >
+   <string>Import schedule</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" >
+    <layout class="QHBoxLayout" name="horizontalLayout_2" >
+     <item>
+      <widget class="QLabel" name="importScheduleLabel" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text" >
+        <string>Import schedule: </string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QGroupBox" name="importAction" >
+       <property name="title" >
+        <string/>
+       </property>
+       <layout class="QHBoxLayout" name="horizontalLayout" >
+        <item>
+         <widget class="QRadioButton" name="update" >
+          <property name="text" >
+           <string>Update</string>
+          </property>
+          <property name="checked" >
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QRadioButton" name="replace" >
+          <property name="text" >
+           <string>Replace</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="online" >
+       <property name="text" >
+        <string>Online</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="proxySettings" >
+       <property name="text" >
+        <string>...</string>
+       </property>
+       <property name="icon" >
+        <iconset resource="../icons.qrc" >
+         <normaloff>:/icons/settings.png</normaloff>:/icons/settings.png</iconset>
+       </property>
+       <property name="autoRaise" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="browse" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text" >
+        <string>Browse</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="cancel" >
+       <property name="text" >
+        <string>Cancel</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QProgressBar" name="progressBar" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+         <horstretch>0</horstretch>
+         <verstretch>10</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="value" >
+        <number>0</number>
+       </property>
+       <property name="textVisible" >
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../icons.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
new file mode 100644 (file)
index 0000000..ad53d9d
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "mainwindow.h"
+
+#include <QTreeView>
+#include <QFile>
+#include <QNetworkProxy>
+
+#include <sqlengine.h>
+
+#include <track.h>
+#include <eventmodel.h>
+#include <delegate.h>
+
+#include <conference.h>
+
+#include <QDialog>
+#include <QMessageBox>
+#include "ui_about.h"
+#include <eventdialog.h>
+#include "daynavigatorwidget.h"
+#include "importschedulewidget.h"
+#include "mapwindow.h"
+
+#include <tabcontainer.h>
+#include <appsettings.h>
+
+const QString PROXY_USERNAME;
+const QString PROXY_PASSWD;
+
+MainWindow::MainWindow(int aEventId, QWidget *aParent)
+    : QMainWindow(aParent)
+{
+    setupUi(this);
+
+#ifdef N810
+    tabWidget->setTabText(1,"Favs");
+    //tabWidget->setTabText(2,"Day");
+#endif
+
+    // first time run aplication: -> let's have it direct connection in this case
+    if(!AppSettings::contains("proxyIsDirectConnection"))
+        AppSettings::setDirectConnection(true);
+
+    if(AppSettings::isDirectConnection())
+    {
+        qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
+    }
+    QNetworkProxy proxy(
+            AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
+            AppSettings::proxyAddress(),
+            AppSettings::proxyPort(),
+            PROXY_USERNAME,
+            PROXY_PASSWD);
+    QNetworkProxy::setApplicationProxy(proxy);
+
+    int confId = Conference::activeConference();
+
+    connect(importScheduleWidget, SIGNAL(scheduleImported(int)), SLOT(scheduleImported(int)));
+
+    // event details have changed
+    connect(dayTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
+    connect(favsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
+    connect(tracksTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
+    connect(roomsTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
+    connect(nowTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
+    connect(searchTabContainer, SIGNAL(eventHasChanged(int,bool)), SLOT(eventHasChanged(int,bool)));
+
+    // event conference map button clicked
+    connect(showMapButton, SIGNAL(clicked()), SLOT(conferenceMapClicked()));
+
+    connect(tabWidget, SIGNAL(infoIconClicked()), SLOT(aboutApp()));
+
+    selectConference->setDuplicatesEnabled(false);
+    int confCount = Conference::getAll().count();
+    if(confCount)
+    {
+        initTabs();
+        fillAndShowConferenceHeader();
+        setWindowTitle(Conference::getById(confId).title());
+
+        if(confCount==1) // don't have to show 'selectConference' widget, if there is only one conference in the DB
+            selectConferenceWidget->hide();
+        else
+        {
+            // have to fill comboBox with available conferences
+            QList<Conference> confs = Conference::getAll();
+            QListIterator<Conference> i(confs);
+            while(i.hasNext())
+            {
+                Conference conf = i.next();
+                selectConference->addItem(conf.title(),conf.id());
+            }
+            int idx = selectConference->findText(Conference::getById(Conference::activeConference()).title());
+            selectConference->setCurrentIndex(idx);
+        }
+        connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
+    }
+    else
+    {
+        conferenceHeader->hide();
+        selectConferenceWidget->hide();
+        // go to the 'conferenceTab', so the user can import the schedule
+        tabWidget->setCurrentIndex(6); // 6 - conference tab
+    }
+
+    // open dialog for given Event ID
+    // this is used in case Alarm Dialog request application to start
+    if(aEventId)
+    {
+        try
+        {
+            EventDialog dialog(aEventId,this);
+            dialog.exec();
+        }
+        catch(OrmNoObjectException&) {} // just start application
+        catch(...) {} // just start application
+    }
+}
+
+void MainWindow::scheduleImported(int aConfId)
+{
+    Q_UNUSED(aConfId);
+
+    Conference conf = Conference::getById(aConfId);
+    if( selectConference->findText(conf.title()) < 0 ) // item doesn't exist
+    {
+        disconnect(selectConference, SIGNAL(currentIndexChanged(int)), this, SLOT(conferenceChanged(int)));
+        selectConference->addItem(conf.title(),conf.id());
+        connect(selectConference, SIGNAL(currentIndexChanged(int)), SLOT(conferenceChanged(int)));
+    }
+    int confCount = Conference::getAll().count();
+    if(confCount)
+    {
+        int idx = selectConference->findText(conf.title());
+        selectConference->setCurrentIndex(idx);
+
+        if(confCount>1)
+            selectConferenceWidget->show();
+
+        conferenceChanged(idx);
+    }
+}
+
+void MainWindow::aboutApp()
+{
+    QDialog dialog(this);
+    Ui::AboutDialog ui;
+    ui.setupUi(&dialog);
+#ifdef N810
+    dialog.setFixedWidth(width());
+#endif
+    dialog.exec();
+}
+
+void MainWindow::conferenceMapClicked()
+{
+    QString mapPath = QString(":/maps/campus.png");
+    if(!QFile::exists(mapPath))
+        mapPath = QString(":/maps/rooms/not-available.png");
+
+    QString roomName;
+
+    QPixmap map(mapPath);
+    MapWindow window(map,roomName,this);
+    window.exec();
+}
+
+void MainWindow::eventHasChanged(int aEventId, bool aReloadModel)
+{
+    dayTabContainer->updateTreeViewModel(aEventId);
+    favsTabContainer->updateTreeViewModel(aEventId,aReloadModel);
+    tracksTabContainer->updateTreeViewModel(aEventId);
+    nowTabContainer->updateTreeViewModel(aEventId);
+    roomsTabContainer->updateTreeViewModel(aEventId);
+    searchTabContainer->updateTreeViewModel(aEventId);
+}
+
+void MainWindow::fillAndShowConferenceHeader()
+{
+    int confId = Conference::activeConference();
+    conferenceTitle->setText(Conference::getById(confId).title());
+    conferenceSubtitle->setText(Conference::getById(confId).subtitle());
+    conferenceWhere->setText(Conference::getById(confId).city() + ", " + Conference::getById(confId).venue());
+    conferenceWhen->setText(
+            Conference::getById(confId).start().toString("dd-MM-yyyy")
+            + ", " +
+            Conference::getById(confId).end().toString("dd-MM-yyyy"));
+    conferenceHeader->show();
+}
+
+void MainWindow::initTabs()
+{
+    int confId = Conference::activeConference();
+    QDate startDate = Conference::getById(confId).start();
+    QDate endDate = Conference::getById(confId).end();
+
+    // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
+    dayTabContainer->setDates(startDate, endDate);
+    tracksTabContainer->setDates(startDate, endDate);
+    roomsTabContainer->setDates(startDate, endDate);
+    favsTabContainer->setDates(startDate, endDate);
+    searchTabContainer->setDates(startDate, endDate);
+    searchTabContainer->searchAgainClicked();
+    nowTabContainer->updateTreeView(QDate::currentDate());
+}
+
+void MainWindow::conferenceChanged(int aIndex)
+{
+    Conference::getById(Conference::activeConference()).update("active",0);
+    Conference::getById(selectConference->itemData(aIndex).toInt()).update("active",1);
+
+    initTabs();
+    fillAndShowConferenceHeader();
+    setWindowTitle(Conference::getById(Conference::activeConference()).title());
+}
+
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
new file mode 100644 (file)
index 0000000..4bf4e82
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/QMainWindow>
+
+#include <ui_mainwindow.h>
+
+class MainWindow : public QMainWindow, private Ui::MainWindow
+{
+    Q_OBJECT
+public:
+    // aEventId is used to inform widget to automatically open
+    // Event dialog for given Event ID
+    MainWindow(int aEventId = 0, QWidget *aParent = NULL);
+    ~MainWindow() {}
+private slots:
+    void scheduleImported(int aConfId);
+    void aboutApp();
+    void conferenceMapClicked();
+    void eventHasChanged(int aEventId, bool aReloadModel);
+    void conferenceChanged(int aIndex);
+private:
+    void fillAndShowConferenceHeader();
+    void initTabs();
+};
+
+#endif /* MAINWINDOW_H */
+
diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui
new file mode 100644 (file)
index 0000000..94765da
--- /dev/null
@@ -0,0 +1,357 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>903</width>
+    <height>498</height>
+   </rect>
+  </property>
+  <property name="minimumSize" >
+   <size>
+    <width>400</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="windowTitle" >
+   <string>FOSDEM Schedule</string>
+  </property>
+  <widget class="QWidget" name="centralwidget" >
+   <layout class="QGridLayout" name="gridLayout" >
+    <item row="0" column="0" >
+     <widget class="TabWidget" name="tabWidget" >
+      <property name="currentIndex" >
+       <number>2</number>
+      </property>
+      <widget class="QWidget" name="nowTab" >
+       <attribute name="title" >
+        <string>Now</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_7" >
+        <item row="0" column="0" >
+         <widget class="NowTabContainer" native="1" name="nowTabContainer" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="favouritesTab" >
+       <attribute name="title" >
+        <string>Favourites</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_3" >
+        <item row="0" column="0" >
+         <widget class="FavTabContainer" native="1" name="favsTabContainer" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="dayViewTab" >
+       <attribute name="title" >
+        <string>Day View</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_2" >
+        <item row="0" column="0" >
+         <widget class="DayViewTabContainer" native="1" name="dayTabContainer" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="tracksTab" >
+       <attribute name="title" >
+        <string>Tracks</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_4" >
+        <item row="0" column="0" >
+         <widget class="TracksTabContainer" native="1" name="tracksTabContainer" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="roomsTab" >
+       <attribute name="title" >
+        <string>Rooms</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_8" >
+        <item row="0" column="0" >
+         <widget class="RoomsTabContainer" native="1" name="roomsTabContainer" />
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="searchTab" >
+       <attribute name="title" >
+        <string>Search</string>
+       </attribute>
+       <layout class="QHBoxLayout" name="horizontalLayout_1" >
+        <item>
+         <widget class="SearchTabContainer" native="1" name="searchTabContainer" >
+          <property name="sizePolicy" >
+           <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="conferenceTab" >
+       <attribute name="title" >
+        <string>Conference</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_5" >
+        <item row="0" column="0" >
+         <layout class="QVBoxLayout" name="verticalLayout_4" >
+          <item>
+           <widget class="QWidget" native="1" name="conferenceHeader" >
+            <layout class="QGridLayout" name="gridLayout_9" >
+             <item row="0" column="0" >
+              <widget class="QLabel" name="conferenceTitle" >
+               <property name="font" >
+                <font>
+                 <weight>75</weight>
+                 <bold>true</bold>
+                </font>
+               </property>
+               <property name="text" >
+                <string>Conference Name</string>
+               </property>
+               <property name="alignment" >
+                <set>Qt::AlignCenter</set>
+               </property>
+               <property name="wordWrap" >
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="0" >
+              <widget class="QLabel" name="conferenceSubtitle" >
+               <property name="text" >
+                <string>Conference Subtitle</string>
+               </property>
+               <property name="alignment" >
+                <set>Qt::AlignCenter</set>
+               </property>
+               <property name="wordWrap" >
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="0" >
+              <widget class="Line" name="line" >
+               <property name="orientation" >
+                <enum>Qt::Horizontal</enum>
+               </property>
+              </widget>
+             </item>
+             <item row="3" column="0" >
+              <layout class="QGridLayout" name="gridLayout_6" >
+               <item row="0" column="0" >
+                <widget class="QLabel" name="label" >
+                 <property name="font" >
+                  <font>
+                   <weight>75</weight>
+                   <italic>true</italic>
+                   <bold>true</bold>
+                  </font>
+                 </property>
+                 <property name="text" >
+                  <string>When:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="0" >
+                <widget class="QLabel" name="label_2" >
+                 <property name="font" >
+                  <font>
+                   <weight>75</weight>
+                   <italic>true</italic>
+                   <bold>true</bold>
+                  </font>
+                 </property>
+                 <property name="text" >
+                  <string>Where:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2" >
+                <widget class="QLabel" name="conferenceWhen" >
+                 <property name="text" >
+                  <string>DATE (FROM - TO)</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="2" >
+                <widget class="QLabel" name="conferenceWhere" >
+                 <property name="text" >
+                  <string>CITY, CAMPUS</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="3" >
+                <widget class="QPushButton" name="showMapButton" >
+                 <property name="text" >
+                  <string>MAP</string>
+                 </property>
+                 <property name="icon" >
+                  <iconset resource="../icons.qrc" >
+                   <normaloff>:/icons/compassBig.png</normaloff>:/icons/compassBig.png</iconset>
+                 </property>
+                 <property name="flat" >
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="4" >
+                <spacer name="horizontalSpacer_3" >
+                 <property name="orientation" >
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0" >
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="0" column="1" >
+                <widget class="QLabel" name="spacer" >
+                 <property name="text" >
+                  <string/>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item row="4" column="0" >
+              <widget class="Line" name="line_2" >
+               <property name="orientation" >
+                <enum>Qt::Horizontal</enum>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="QWidget" native="1" name="selectConferenceWidget" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <layout class="QHBoxLayout" name="horizontalLayout" >
+             <item>
+              <widget class="QLabel" name="selectConferenceLabel" >
+               <property name="text" >
+                <string>Select conference: </string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <spacer name="horizontalSpacer" >
+               <property name="orientation" >
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0" >
+                <size>
+                 <width>40</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item>
+              <widget class="QComboBox" name="selectConference" >
+               <property name="sizePolicy" >
+                <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="ImportScheduleWidget" native="1" name="importScheduleWidget" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="verticalSpacer" >
+            <property name="orientation" >
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0" >
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>TabWidget</class>
+   <extends>QTabWidget</extends>
+   <header>tabwidget.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>ImportScheduleWidget</class>
+   <extends>QWidget</extends>
+   <header>importschedulewidget.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>SearchTabContainer</class>
+   <extends>QWidget</extends>
+   <header>searchtabcontainer.h</header>
+  </customwidget>
+  <customwidget>
+   <class>DayViewTabContainer</class>
+   <extends>QWidget</extends>
+   <header>dayviewtabcontainer.h</header>
+  </customwidget>
+  <customwidget>
+   <class>FavTabContainer</class>
+   <extends>QWidget</extends>
+   <header>favtabcontainer.h</header>
+  </customwidget>
+  <customwidget>
+   <class>TracksTabContainer</class>
+   <extends>QWidget</extends>
+   <header>trackstabcontainer.h</header>
+  </customwidget>
+  <customwidget>
+   <class>RoomsTabContainer</class>
+   <extends>QWidget</extends>
+   <header>roomstabcontainer.h</header>
+  </customwidget>
+  <customwidget>
+   <class>NowTabContainer</class>
+   <extends>QWidget</extends>
+   <header>nowtabcontainer.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="../icons.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/mapwindow.cpp b/src/gui/mapwindow.cpp
new file mode 100644 (file)
index 0000000..6178c55
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "mapwindow.h"
+
+MapWindow::MapWindow(const QPixmap &aImage, const QString &aName, QWidget *aParent)
+    : QDialog(aParent)
+{
+    setupUi(this);
+#ifdef MAEMO
+    showFullScreen();
+    //map->setScaledContents(true);
+    //map->setPixmap(aImage.scaled(QSize(800,480),Qt::KeepAspectRatioByExpanding,Qt::SmoothTransformation));
+    map->setPixmap(aImage.scaled(QSize(640,480),Qt::KeepAspectRatioByExpanding,Qt::SmoothTransformation));
+#elif N810
+    showMaximized();
+    map->setPixmap(aImage.scaled(QSize(400,300),Qt::KeepAspectRatioByExpanding,Qt::SmoothTransformation));
+#else
+    map->setPixmap(aImage);
+#endif
+    setMouseTracking(true); // to receive mouse events
+    setWindowTitle(aName);
+}
+
+// it is enough to handle mouseReleaseEvent, instead of
+// getting/creating mouseClikEvent, since the whole window
+// is occupied by only-one widget/label (image/map)
+void MapWindow::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_UNUSED(event);
+    close();
+}
+
diff --git a/src/gui/mapwindow.h b/src/gui/mapwindow.h
new file mode 100644 (file)
index 0000000..68f5396
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MAPWINDOW_H
+#define MAPWINDOW_H
+
+#include <QDialog>
+#include <QPixmap>
+#include "ui_mapwindow.h"
+
+class MapWindow : public QDialog, Ui::MapWindow
+{
+public:
+    MapWindow(const QPixmap &aImage, const QString &aName, QWidget *aParent = NULL);
+    ~MapWindow() {}
+protected:
+    virtual void mouseReleaseEvent(QMouseEvent *event);
+};
+
+#endif /* MAPWINDOW_H */
+
diff --git a/src/gui/mapwindow.ui b/src/gui/mapwindow.ui
new file mode 100644 (file)
index 0000000..36bac1b
--- /dev/null
@@ -0,0 +1,42 @@
+<ui version="4.0" >
+ <class>MapWindow</class>
+ <widget class="QDialog" name="MapWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>298</width>
+    <height>179</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle" >
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" >
+    <widget class="QLabel" name="map" >
+     <property name="sizePolicy" >
+      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text" >
+      <string>Map goes here</string>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/nowtabcontainer.cpp b/src/gui/nowtabcontainer.cpp
new file mode 100644 (file)
index 0000000..81795a6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <QTimer>
+#include "nowtabcontainer.h"
+
+NowTabContainer::NowTabContainer( QWidget *aParent ) : TabContainer( aParent )
+{
+    QTimer *timer = new QTimer( this );
+    connect( timer, SIGNAL(timeout()), SLOT(timerUpdateTreeView()) );
+    timer->start( 30000); // 30 seconds timer
+}
+
+void NowTabContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    Q_UNUSED( aDate );
+
+    static_cast<EventModel*>(treeView->model())->loadNowEvents( aConferenceId );
+    dayNavigator->hide();
+}
+
+void NowTabContainer::timerUpdateTreeView()
+{
+    updateTreeView( QDate() );
+}
+
+void NowTabContainer::updateTreeView(const QDate &aDate)
+{
+    TabContainer::updateTreeView(aDate);
+    treeView->setAllExpanded(true);
+}
+
diff --git a/src/gui/nowtabcontainer.h b/src/gui/nowtabcontainer.h
new file mode 100644 (file)
index 0000000..0bc0adc
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NOWTABCONTAINER_H_
+#define NOWTABCONTAINER_H_
+
+#include "tabcontainer.h"
+
+class NowTabContainer: public TabContainer
+{
+    Q_OBJECT
+public:
+    NowTabContainer( QWidget *aParent );
+    virtual ~NowTabContainer() { }
+
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId );
+
+public slots:
+    virtual void updateTreeView(const QDate &aDate);
+
+private slots:
+    void timerUpdateTreeView();
+};
+
+#endif /* NOWTABCONTAINER_H_ */
diff --git a/src/gui/proxysettingsdialog.cpp b/src/gui/proxysettingsdialog.cpp
new file mode 100644 (file)
index 0000000..844e54d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "proxysettingsdialog.h"
+
+#include <appsettings.h>
+#include <QDebug>
+
+ProxySettingsDialog::ProxySettingsDialog(QWidget *aParent)
+    : QDialog(aParent)
+{
+    setupUi(this);
+
+    // deserialize dialog data
+    address->setText(AppSettings::proxyAddress());
+    port->setValue(AppSettings::proxyPort());
+    directConnection->setChecked(AppSettings::isDirectConnection());
+
+    connect(okButton, SIGNAL(clicked()), SLOT(saveDialogData()));
+    connect(directConnection, SIGNAL(clicked(bool)), SLOT(connectionTypeChanged(bool)));
+
+    if(directConnection->isChecked())
+        proxyWidget->hide();
+}
+
+void ProxySettingsDialog::connectionTypeChanged(bool aState)
+{
+    aState ? proxyWidget->hide() : proxyWidget->show();
+}
+
+void ProxySettingsDialog::saveDialogData()
+{
+    // serialize dialog data
+    AppSettings::setProxyAddress(address->text());
+    AppSettings::setProxyPort(port->value());
+    AppSettings::setDirectConnection(directConnection->isChecked());
+
+    close();
+}
+
diff --git a/src/gui/proxysettingsdialog.h b/src/gui/proxysettingsdialog.h
new file mode 100644 (file)
index 0000000..d13f9f1
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef PROXYSETTINGSDIALOG_H
+#define PROXYSETTINGSDIALOG_H
+
+#include <QDialog>
+#include "ui_proxysettingsdialog.h"
+
+class ProxySettingsDialog : public QDialog, Ui::ProxySettingsDialog
+{
+    Q_OBJECT
+public:
+    ProxySettingsDialog(QWidget *aParent = NULL);
+    ~ProxySettingsDialog() {}
+private slots:
+    void connectionTypeChanged(bool aState);
+    void saveDialogData();
+};
+
+#endif /* PROXYSETTINGSDIALOG_H */  
+
diff --git a/src/gui/proxysettingsdialog.ui b/src/gui/proxysettingsdialog.ui
new file mode 100644 (file)
index 0000000..2b85c58
--- /dev/null
@@ -0,0 +1,106 @@
+<ui version="4.0" >
+ <class>ProxySettingsDialog</class>
+ <widget class="QDialog" name="ProxySettingsDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>469</width>
+    <height>146</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="MinimumExpanding" hsizetype="Preferred" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle" >
+   <string>Proxy settings</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" >
+   <item>
+    <widget class="QCheckBox" name="directConnection" >
+     <property name="text" >
+      <string>Direct connection</string>
+     </property>
+     <property name="checked" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" native="1" name="proxyWidget" >
+     <layout class="QHBoxLayout" name="horizontalLayout_3" >
+      <item>
+       <widget class="QLabel" name="label" >
+        <property name="text" >
+         <string>Address: </string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="address" />
+      </item>
+      <item>
+       <widget class="QLabel" name="label_2" >
+        <property name="text" >
+         <string>Port:</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QSpinBox" name="port" >
+        <property name="maximum" >
+         <number>9999</number>
+        </property>
+        <property name="value" >
+         <number>8080</number>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer" >
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0" >
+      <size>
+       <width>20</width>
+       <height>10</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" >
+     <item>
+      <spacer name="horizontalSpacer" >
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="okButton" >
+       <property name="text" >
+        <string>OK</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/roomstabcontainer.cpp b/src/gui/roomstabcontainer.cpp
new file mode 100644 (file)
index 0000000..1c8165b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "roomstabcontainer.h"
+
+RoomsTabContainer::RoomsTabContainer( QWidget *aParent ) : TabContainer( aParent )
+{
+}
+
+void RoomsTabContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    static_cast<EventModel*>(treeView->model())->loadEventsByRoom( aDate, aConferenceId );
+}
diff --git a/src/gui/roomstabcontainer.h b/src/gui/roomstabcontainer.h
new file mode 100644 (file)
index 0000000..4157699
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ROOMSTABCONTAINER_H_
+#define ROOMSTABCONTAINER_H_
+
+#include "tabcontainer.h"
+
+class RoomsTabContainer: public TabContainer
+{
+    Q_OBJECT
+public:
+    RoomsTabContainer( QWidget *aParent );
+    virtual ~RoomsTabContainer() {}
+
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId );
+
+};
+
+#endif /* ROOMSTABCONTAINER_H_ */
diff --git a/src/gui/searchhead.cpp b/src/gui/searchhead.cpp
new file mode 100644 (file)
index 0000000..e4b6d0f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "searchhead.h"
+
+SearchHead::SearchHead(QWidget *parent)
+    : QWidget(parent)
+{
+       setupUi(this);
+       connect( searchButton, SIGNAL(clicked()), SLOT(searchButtonClicked()));
+}
+
+SearchHead::~SearchHead()
+{
+
+}
+
+
+void SearchHead::searchButtonClicked()
+{
+    qDebug() << "SearchHead::searchButtonClicked()";
+    emit( searchClicked() );
+}
diff --git a/src/gui/searchhead.h b/src/gui/searchhead.h
new file mode 100644 (file)
index 0000000..b957f73
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef SEARCHHEAD_H
+#define SEARCHHEAD_H
+
+#include <QtGui/QWidget>
+#include <QDebug>
+#include "ui_searchhead.h"
+
+class SearchHead : public QWidget, public Ui::SearchHeadClass
+{
+    Q_OBJECT
+
+public:
+    SearchHead(QWidget *parent = 0);
+    ~SearchHead();
+
+signals:
+    void searchClicked();
+
+private slots:
+    void searchButtonClicked();
+
+//private:
+    //Ui::SearchHeadClass ui;
+};
+
+#endif // SEARCHHEAD_H
diff --git a/src/gui/searchhead.ui b/src/gui/searchhead.ui
new file mode 100644 (file)
index 0000000..bb8ca37
--- /dev/null
@@ -0,0 +1,136 @@
+<ui version="4.0" >
+ <class>SearchHeadClass</class>
+ <widget class="QWidget" name="SearchHeadClass" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>371</width>
+    <height>88</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="Minimum" hsizetype="Expanding" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize" >
+   <size>
+    <width>10</width>
+    <height>10</height>
+   </size>
+  </property>
+  <property name="windowTitle" >
+   <string>SearchHead</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" >
+   <property name="leftMargin" >
+    <number>9</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_7" >
+     <item>
+      <widget class="QCheckBox" name="searchTitle" >
+       <property name="text" >
+        <string>Title</string>
+       </property>
+       <property name="checked" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="searchAbstract" >
+       <property name="text" >
+        <string>Abstract</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="searchSpeaker" >
+       <property name="text" >
+        <string>Speaker</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="searchTag" >
+       <property name="text" >
+        <string>Tag</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QCheckBox" name="searchRoom" >
+       <property name="text" >
+        <string>Room</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2" >
+     <item>
+      <widget class="QLineEdit" name="searchEdit" >
+       <property name="enabled" >
+        <bool>true</bool>
+       </property>
+       <property name="toolTip" >
+        <string>type a keyword to search</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="searchButton" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text" >
+        <string>Search</string>
+       </property>
+       <property name="icon" >
+        <iconset resource="../icons.qrc" >
+         <normaloff>:/icons/search.png</normaloff>:/icons/search.png</iconset>
+       </property>
+       <property name="checkable" >
+        <bool>false</bool>
+       </property>
+       <property name="autoDefault" >
+        <bool>true</bool>
+       </property>
+       <property name="default" >
+        <bool>true</bool>
+       </property>
+       <property name="flat" >
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer" >
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0" >
+      <size>
+       <width>20</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources>
+  <include location="../icons.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/searchtabcontainer.cpp b/src/gui/searchtabcontainer.cpp
new file mode 100644 (file)
index 0000000..70921af
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "searchtabcontainer.h"
+#include "searchhead.h"
+#include <QMessageBox>
+
+SearchTabContainer::SearchTabContainer(QWidget *aParent) : TabContainer( aParent )
+{
+    header = new SearchHead(this);
+    header->setObjectName(QString::fromUtf8("header"));
+    QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
+    sizePolicy.setHorizontalStretch(0);
+    sizePolicy.setVerticalStretch(0);
+    //sizePolicy.setHeightForWidth(TabContainer::sizePolicy().hasHeightForWidth());
+    sizePolicy.setHeightForWidth(header->sizePolicy().hasHeightForWidth());
+    header->setSizePolicy(sizePolicy);
+    header->setMinimumSize(QSize(10, 10));
+
+    verticalLayout->insertWidget(0,header);
+
+    header->show();
+
+    searchAgainButton = new QToolButton(this);
+    searchAgainButton->setObjectName(QString::fromUtf8("button"));
+    QIcon icon;
+    icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/search.png")), QIcon::Normal, QIcon::Off);
+    searchAgainButton->setIcon(icon);
+    QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Minimum);
+    sizePolicy1.setHorizontalStretch(0);
+    sizePolicy1.setVerticalStretch(0);
+    sizePolicy1.setHeightForWidth(searchAgainButton->sizePolicy().hasHeightForWidth());
+    searchAgainButton->setSizePolicy(sizePolicy1);
+
+    verticalLayout_2->insertWidget(0,searchAgainButton);
+
+    searchAgainButton->hide();
+    treeView->hide();
+    // do not show 'search' header if there are no conferences in the DB
+    if(Conference::getAll().count()==0)
+    {
+        header->hide();
+    }
+
+    connect( header, SIGNAL(searchClicked()), SLOT(searchButtonClicked()));
+    connect( searchAgainButton, SIGNAL(clicked()), SLOT(searchAgainClicked()));
+}
+
+SearchTabContainer::~SearchTabContainer()
+{
+}
+
+void SearchTabContainer::searchButtonClicked()
+{
+    QHash<QString,QString> columns;
+
+    SearchHead *searchHeader = static_cast<SearchHead*>(header);
+    if( searchHeader->searchTitle->isChecked() )
+        columns.insertMulti("EVENT", "title");
+    if( searchHeader->searchAbstract->isChecked() )
+        columns.insertMulti("EVENT", "abstract");
+    if( searchHeader->searchTag->isChecked() )
+        columns.insertMulti("EVENT", "tag");
+    if( searchHeader->searchSpeaker->isChecked() )
+        columns["PERSON"] = "name";
+    if( searchHeader->searchRoom->isChecked() )
+        columns["ROOM"] = "name";
+
+    QString keyword = searchHeader->searchEdit->text().replace( QString("%"), QString("\\%") );
+    //qDebug() << "\nKeyword to search: " << keyword;
+
+    int confId = Conference::activeConference();
+    SqlEngine::searchEvent( confId, columns, keyword );
+
+    QDate startDate = Conference::getById(confId).start();
+    QDate endDate = Conference::getById(confId).end();
+
+    int nrofFounds = 0;
+    QDate firstDateWithFounds = endDate;
+    QDate lastDateWithFounds = startDate;
+    for(QDate d=startDate; d<=endDate; d=d.addDays(1))
+    {
+        try{
+            int count = Event::getSearchResultByDate(d, confId, "start").count();
+            if(count && (firstDateWithFounds==endDate))
+                firstDateWithFounds=d;
+            if(count)
+                lastDateWithFounds=d;
+            nrofFounds+=count;
+        }
+        catch( OrmException &e  ){
+            qDebug() << "Event::getSearchResultByDate failed: " << e.text();
+        }
+        catch(...){
+            qDebug() << "Event::getSearchResultByDate failed";
+        }
+    }
+
+    if(!nrofFounds)
+    {
+        // TODO: display some message
+        treeView->hide();
+        searchAgainButton->hide();
+        dayNavigator->hide();
+        header->show();
+        QMessageBox::information(
+                this,
+                QString("Keyword '%1' not found!").arg(keyword),
+                QString("No events containing '%1' found!").arg(keyword),
+                QMessageBox::Ok);
+    }
+    else
+    {
+        searchAgainButton->show();
+        dayNavigator->show();
+        treeView->show();
+        header->hide();
+
+        updateTreeView( firstDateWithFounds );
+        dayNavigator->setDates(firstDateWithFounds, lastDateWithFounds);
+    }
+}
+
+void SearchTabContainer::searchAgainClicked()
+{
+    header->show();
+    searchAgainButton->hide();
+    dayNavigator->hide();
+    treeView->hide();
+}
+
+void SearchTabContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    static_cast<EventModel*>(treeView->model())->loadSearchResultEvents( aDate, aConferenceId );
+}
+
diff --git a/src/gui/searchtabcontainer.h b/src/gui/searchtabcontainer.h
new file mode 100644 (file)
index 0000000..83f3d39
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SEARCHTAB_H_
+#define SEARCHTAB_H_
+
+#include <QWidget>
+
+#include "tabcontainer.h"
+#include "searchhead.h"
+
+class SearchTabContainer: public TabContainer {
+    Q_OBJECT
+public:
+    SearchTabContainer(QWidget *aParent);
+    virtual ~SearchTabContainer();
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId );
+public slots:
+    void searchAgainClicked(); // made it public - to show header when 1.st conf importing is done successfuly
+private slots:
+    void searchButtonClicked();
+
+private:
+    SearchHead *header;
+    QToolButton *searchAgainButton;
+};
+
+#endif /* SEARCHTAB_H_ */
diff --git a/src/gui/tabcontainer.cpp b/src/gui/tabcontainer.cpp
new file mode 100644 (file)
index 0000000..04c1bd9
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "tabcontainer.h"
+
+#include <QFile>
+#include <QMessageBox>
+#include <QTimer>
+
+#include <treeview.h>
+#include <delegate.h>
+
+#include "eventdialog.h"
+#include "mapwindow.h"
+
+#include "conflictsdialog.h"
+
+TabContainer::TabContainer(QWidget *aParent)
+    : QWidget(aParent)
+{
+    setupUi(this);
+
+    treeView->setHeaderHidden(true);
+    treeView->setRootIsDecorated(false);
+    treeView->setIndentation(0);
+    treeView->setAnimated(true);
+    treeView->setModel(new EventModel());
+    treeView->setItemDelegate(new Delegate(treeView));
+
+    connect(dayNavigator, SIGNAL(dateChanged(const QDate &)), SLOT(updateTreeView(const QDate &)));
+
+    connect(treeView, SIGNAL(eventHasChanged(int,bool)), SIGNAL(eventHasChanged(int,bool)));
+    connect(treeView, SIGNAL(clicked(const QModelIndex &)), SLOT(itemClicked(const QModelIndex &)));
+    connect(treeView, SIGNAL(requestForMap(const QModelIndex &)), SLOT(displayMap(const QModelIndex &)));
+    connect(treeView, SIGNAL(requestForConflicts(const QModelIndex &)), SLOT(displayConflicts(const QModelIndex &)));
+
+    // day navigator is hidden by default
+    dayNavigator->hide();
+}
+
+void TabContainer::updateTreeView(const QDate &aDate)
+{
+    dayNavigator->show();
+    loadEvents( aDate, Conference::activeConference() );
+    treeView->reset();
+}
+
+void TabContainer::itemClicked(const QModelIndex &aIndex)
+{
+    // have to handle only events, not time-groups
+    if(!aIndex.parent().isValid()) // time-group
+        return;
+
+    EventDialog dialog(static_cast<Event*>(aIndex.internalPointer())->id(),this);
+#ifdef N810
+    dialog.setFixedWidth(static_cast<QWidget*>(parent())->width());
+#endif
+    connect(&dialog, SIGNAL(eventHasChanged(int,bool)), this, SIGNAL(eventHasChanged(int,bool)));
+    dialog.exec();
+    disconnect(&dialog, SIGNAL(eventHasChanged(int,bool)), this, SIGNAL(eventHasChanged(int,bool)));
+}
+
+void TabContainer::displayMap(const QModelIndex &aIndex)
+{
+    Event *event = static_cast<Event*>(aIndex.internalPointer());
+
+    // room names are stored in lower-case format
+    // room names are stored without dots in the name, eg. "aw.1124.png" -> "aw1124.png"
+    QString mapPath = QString(":/maps/rooms/%1.png").arg(event->room().toLower().remove("."));
+    if(!QFile::exists(mapPath))
+        mapPath = QString(":/maps/rooms/not-available.png");
+
+    QString roomName;
+    if(mapPath.contains("not-available", Qt::CaseInsensitive))
+        roomName = QString("Map is not available: %1").arg(event->room());
+    else
+        roomName = event->room();
+
+    QPixmap map(mapPath);
+    MapWindow window(map,roomName,this);
+    window.exec();
+}
+
+void TabContainer::displayConflicts(const QModelIndex &aIndex)
+{
+    ConflictsDialog dialog(static_cast<Event*>(aIndex.internalPointer())->id(),this);
+#ifdef N810
+    dialog.setFixedWidth(static_cast<QWidget*>(parent())->width());
+#endif
+    connect(&dialog, SIGNAL(eventHasChanged(int,bool)), this, SIGNAL(eventHasChanged(int,bool)));
+    dialog.exec();
+    disconnect(&dialog, SIGNAL(eventHasChanged(int,bool)), this, SIGNAL(eventHasChanged(int,bool)));
+}
+
+void TabContainer::updateTreeViewModel(int aEventId, bool aReloadModel)
+{
+    if(aReloadModel)
+    {
+        // requires special handling
+        // eg. in case of favourities - some favourities may have changed
+        // and so we need to reload them
+        int confId = Conference::activeConference();
+        QDate startDate = Conference::getById(confId).start();
+        QDate endDate = Conference::getById(confId).end();
+        dayNavigator->setDates(startDate, endDate);
+        updateTreeView( Conference::getById(confId).start() );
+    }
+    else
+    {
+        // just update event in the question
+        static_cast<EventModel*>(treeView->model())->updateModel(aEventId);
+    }
+}
+
+void TabContainer::setDates(const QDate &aStart, const QDate &aEnd)
+{
+    dayNavigator->setDates(aStart, aEnd);
+}
+
diff --git a/src/gui/tabcontainer.h b/src/gui/tabcontainer.h
new file mode 100644 (file)
index 0000000..e292c06
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TABCONTAINER_H
+#define TABCONTAINER_H
+
+#include <QWidget>
+#include "ui_tabcontainer.h"
+
+#include <conference.h>
+#include <sqlengine.h>
+#include <conference.h>
+#include <eventmodel.h>
+
+class TabContainer : public QWidget, public Ui::TabContainer
+{
+    Q_OBJECT
+public:
+
+    TabContainer(QWidget *aParent = NULL);
+    virtual ~TabContainer() {}
+
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId )
+    {
+        Q_UNUSED(aDate);
+        Q_UNUSED(aConferenceId);
+    };
+
+signals:
+    void eventHasChanged(int aEventId, bool aReloadModel);
+
+public slots:
+    virtual void updateTreeViewModel(int aEventId, bool aReloadModel = false);
+    void setDates(const QDate &aStart, const QDate &aEnd);
+
+protected slots:
+    virtual void updateTreeView(const QDate &aDate);
+    void itemClicked(const QModelIndex &aIndex);
+    void displayMap(const QModelIndex &aIndex);
+    void displayConflicts(const QModelIndex &aIndex);
+};
+
+#endif /* TABCONTAINER_H */
+
diff --git a/src/gui/tabcontainer.ui b/src/gui/tabcontainer.ui
new file mode 100644 (file)
index 0000000..77dcfde
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TabContainer</class>
+ <widget class="QWidget" name="TabContainer">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>568</width>
+    <height>292</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item row="0" column="2">
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <widget class="TreeView" name="treeView">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>1</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="0" column="1">
+    <layout class="QVBoxLayout" name="verticalLayout_2">
+     <item>
+      <widget class="DayNavigatorWidget" name="dayNavigator" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>10</width>
+         <height>10</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>DayNavigatorWidget</class>
+   <extends>QWidget</extends>
+   <header>daynavigatorwidget.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>TreeView</class>
+   <extends>QTreeView</extends>
+   <header>../mvc/treeview.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="../icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/tabwidget.cpp b/src/gui/tabwidget.cpp
new file mode 100644 (file)
index 0000000..53e1f38
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "tabwidget.h"
+
+#include <QMouseEvent>
+#include <QPainter>
+#include <QTabBar>
+
+TabWidget::TabWidget(QWidget *aParent)
+    : QTabWidget(aParent)
+    , mPressPoint(0,0)
+{
+    mInfoImage = QImage(":/icons/info.png");
+}
+
+void TabWidget::paintEvent(QPaintEvent *event)
+{
+    Q_UNUSED(event);
+
+    int height = tabBar()->tabRect(currentIndex()).height();
+    QImage image = mInfoImage.scaled(QSize(height,height),Qt::KeepAspectRatioByExpanding,Qt::SmoothTransformation);
+    QPainter painter(this);
+    painter.drawImage(rect().topRight()-QPoint(image.width(),0),image);
+}
+
+void TabWidget::mousePressEvent(QMouseEvent *event)
+{
+    mPressPoint = event->pos();
+}
+
+void TabWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+    int height = tabBar()->tabRect(currentIndex()).height();
+    QImage image = mInfoImage.scaled(QSize(height,height),Qt::KeepAspectRatioByExpanding,Qt::SmoothTransformation);
+    QPoint topLeft = rect().topRight()-QPoint(image.width(),0);
+    QRect infoRect = QRect(topLeft, topLeft+QPoint(image.width(),image.height()));
+    if( (infoRect.contains(event->pos())) && (infoRect.contains(mPressPoint)) )
+    {
+        emit(infoIconClicked());
+    }
+}
+
diff --git a/src/gui/tabwidget.h b/src/gui/tabwidget.h
new file mode 100644 (file)
index 0000000..af9adbb
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TABWIDGET_H
+#define TABWIDGET_H
+
+#include <QTabWidget>
+
+class TabWidget : public QTabWidget
+{
+    Q_OBJECT
+public:
+    TabWidget(QWidget *aParent = NULL);
+    ~TabWidget() {}
+protected:
+    void paintEvent(QPaintEvent *event);
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+signals:
+    void infoIconClicked();
+private:
+    QPoint mPressPoint;
+    QImage mInfoImage;
+};
+
+#endif /* TABWIDGET_H */
+
diff --git a/src/gui/trackstabcontainer.cpp b/src/gui/trackstabcontainer.cpp
new file mode 100644 (file)
index 0000000..8cd742b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "trackstabcontainer.h"
+
+TracksTabContainer::TracksTabContainer( QWidget *aParent ) : TabContainer( aParent )
+{
+}
+
+void TracksTabContainer::loadEvents( const QDate &aDate, const int aConferenceId )
+{
+    static_cast<EventModel*>(treeView->model())->loadEventsByTrack( aDate, aConferenceId );
+}
diff --git a/src/gui/trackstabcontainer.h b/src/gui/trackstabcontainer.h
new file mode 100644 (file)
index 0000000..b521209
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRACKSTABCONTAINER_H_
+#define TRACKSTABCONTAINER_H_
+
+#include "tabcontainer.h"
+
+class TracksTabContainer: public TabContainer
+{
+    Q_OBJECT
+public:
+    TracksTabContainer( QWidget *aParent );
+    virtual ~TracksTabContainer() {}
+
+protected:
+    virtual void loadEvents( const QDate &aDate, const int aConferenceId );
+
+};
+
+#endif /* TRACKSTABCONTAINER_H_ */
diff --git a/src/icons.qrc b/src/icons.qrc
new file mode 100644 (file)
index 0000000..0e64f06
--- /dev/null
@@ -0,0 +1,17 @@
+<RCC>
+    <qresource prefix="/">
+        <file>icons/expand.png</file>
+        <file>icons/collapse.png</file>
+        <file>icons/fosdem.png</file>
+        <file>icons/brain-alone.png</file>
+        <file>icons/alarm-offBig.png</file>
+        <file>icons/alarm-onBig.png</file>
+        <file>icons/compassBig.png</file>
+        <file>icons/favourite-offBig.png</file>
+        <file>icons/favourite-onBig.png</file>
+        <file>icons/exclamation.png</file>
+        <file>icons/info.png</file>
+        <file>icons/search.png</file>
+        <file>icons/settings.png</file>
+    </qresource>
+</RCC>
diff --git a/src/icons/alarm-offBig.png b/src/icons/alarm-offBig.png
new file mode 100644 (file)
index 0000000..3efd1a3
Binary files /dev/null and b/src/icons/alarm-offBig.png differ
diff --git a/src/icons/alarm-onBig.png b/src/icons/alarm-onBig.png
new file mode 100644 (file)
index 0000000..417263b
Binary files /dev/null and b/src/icons/alarm-onBig.png differ
diff --git a/src/icons/brain-alone.png b/src/icons/brain-alone.png
new file mode 100644 (file)
index 0000000..514a6fa
Binary files /dev/null and b/src/icons/brain-alone.png differ
diff --git a/src/icons/collapse.png b/src/icons/collapse.png
new file mode 100644 (file)
index 0000000..b3a0825
Binary files /dev/null and b/src/icons/collapse.png differ
diff --git a/src/icons/compassBig.png b/src/icons/compassBig.png
new file mode 100644 (file)
index 0000000..1dcc34d
Binary files /dev/null and b/src/icons/compassBig.png differ
diff --git a/src/icons/exclamation.png b/src/icons/exclamation.png
new file mode 100644 (file)
index 0000000..91065fb
Binary files /dev/null and b/src/icons/exclamation.png differ
diff --git a/src/icons/expand.png b/src/icons/expand.png
new file mode 100644 (file)
index 0000000..4dfcdc6
Binary files /dev/null and b/src/icons/expand.png differ
diff --git a/src/icons/favourite-offBig.png b/src/icons/favourite-offBig.png
new file mode 100644 (file)
index 0000000..5dd9f70
Binary files /dev/null and b/src/icons/favourite-offBig.png differ
diff --git a/src/icons/favourite-onBig.png b/src/icons/favourite-onBig.png
new file mode 100644 (file)
index 0000000..6f27481
Binary files /dev/null and b/src/icons/favourite-onBig.png differ
diff --git a/src/icons/fosdem.png b/src/icons/fosdem.png
new file mode 100644 (file)
index 0000000..c733163
Binary files /dev/null and b/src/icons/fosdem.png differ
diff --git a/src/icons/info.png b/src/icons/info.png
new file mode 100644 (file)
index 0000000..78c891d
Binary files /dev/null and b/src/icons/info.png differ
diff --git a/src/icons/search.png b/src/icons/search.png
new file mode 100644 (file)
index 0000000..0dacd00
Binary files /dev/null and b/src/icons/search.png differ
diff --git a/src/icons/settings.png b/src/icons/settings.png
new file mode 100644 (file)
index 0000000..bc255ef
Binary files /dev/null and b/src/icons/settings.png differ
diff --git a/src/maps.qrc b/src/maps.qrc
new file mode 100644 (file)
index 0000000..de7c368
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>maps/campus.png</file>
+    <file>maps/rooms/aw1105.png</file>
+    <file>maps/rooms/aw1115.png</file>
+    <file>maps/rooms/aw1117.png</file>
+    <file>maps/rooms/aw1120.png</file>
+    <file>maps/rooms/aw1121.png</file>
+    <file>maps/rooms/aw1124.png</file>
+    <file>maps/rooms/aw1125.png</file>
+    <file>maps/rooms/aw1126.png</file>
+    <file>maps/rooms/chavanne.png</file>
+    <file>maps/rooms/ferrer.png</file>
+    <file>maps/rooms/guillissen.png</file>
+    <file>maps/rooms/h1301.png</file>
+    <file>maps/rooms/h1302.png</file>
+    <file>maps/rooms/h1308.png</file>
+    <file>maps/rooms/h1309.png</file>
+    <file>maps/rooms/h2111.png</file>
+    <file>maps/rooms/h2213.png</file>
+    <file>maps/rooms/h2214.png</file>
+    <file>maps/rooms/H-WC.png</file>
+    <file>maps/rooms/infodesk.png</file>
+    <file>maps/rooms/janson.png</file>
+    <file>maps/rooms/lameere.png</file>
+    <file>maps/rooms/ua2114.png</file>
+    <file>maps/rooms/not-available.png</file>
+</qresource>
+</RCC>
+
diff --git a/src/maps/campus.png b/src/maps/campus.png
new file mode 100644 (file)
index 0000000..64346c2
Binary files /dev/null and b/src/maps/campus.png differ
diff --git a/src/maps/rooms/H-WC.png b/src/maps/rooms/H-WC.png
new file mode 100644 (file)
index 0000000..b5914b4
Binary files /dev/null and b/src/maps/rooms/H-WC.png differ
diff --git a/src/maps/rooms/aw1105.png b/src/maps/rooms/aw1105.png
new file mode 100644 (file)
index 0000000..ce56059
Binary files /dev/null and b/src/maps/rooms/aw1105.png differ
diff --git a/src/maps/rooms/aw1115.png b/src/maps/rooms/aw1115.png
new file mode 100644 (file)
index 0000000..54da95b
Binary files /dev/null and b/src/maps/rooms/aw1115.png differ
diff --git a/src/maps/rooms/aw1117.png b/src/maps/rooms/aw1117.png
new file mode 100644 (file)
index 0000000..8829414
Binary files /dev/null and b/src/maps/rooms/aw1117.png differ
diff --git a/src/maps/rooms/aw1120.png b/src/maps/rooms/aw1120.png
new file mode 100644 (file)
index 0000000..d2b63c4
Binary files /dev/null and b/src/maps/rooms/aw1120.png differ
diff --git a/src/maps/rooms/aw1121.png b/src/maps/rooms/aw1121.png
new file mode 100644 (file)
index 0000000..0f747d5
Binary files /dev/null and b/src/maps/rooms/aw1121.png differ
diff --git a/src/maps/rooms/aw1124.png b/src/maps/rooms/aw1124.png
new file mode 100644 (file)
index 0000000..d3dc6fd
Binary files /dev/null and b/src/maps/rooms/aw1124.png differ
diff --git a/src/maps/rooms/aw1125.png b/src/maps/rooms/aw1125.png
new file mode 100644 (file)
index 0000000..542b03d
Binary files /dev/null and b/src/maps/rooms/aw1125.png differ
diff --git a/src/maps/rooms/aw1126.png b/src/maps/rooms/aw1126.png
new file mode 100644 (file)
index 0000000..83d1630
Binary files /dev/null and b/src/maps/rooms/aw1126.png differ
diff --git a/src/maps/rooms/chavanne.png b/src/maps/rooms/chavanne.png
new file mode 100644 (file)
index 0000000..4108e1c
Binary files /dev/null and b/src/maps/rooms/chavanne.png differ
diff --git a/src/maps/rooms/ferrer.png b/src/maps/rooms/ferrer.png
new file mode 100644 (file)
index 0000000..39cc6ef
Binary files /dev/null and b/src/maps/rooms/ferrer.png differ
diff --git a/src/maps/rooms/guillissen.png b/src/maps/rooms/guillissen.png
new file mode 100644 (file)
index 0000000..392828c
Binary files /dev/null and b/src/maps/rooms/guillissen.png differ
diff --git a/src/maps/rooms/h1301.png b/src/maps/rooms/h1301.png
new file mode 100644 (file)
index 0000000..a1b76b0
Binary files /dev/null and b/src/maps/rooms/h1301.png differ
diff --git a/src/maps/rooms/h1302.png b/src/maps/rooms/h1302.png
new file mode 100644 (file)
index 0000000..ff8eeef
Binary files /dev/null and b/src/maps/rooms/h1302.png differ
diff --git a/src/maps/rooms/h1308.png b/src/maps/rooms/h1308.png
new file mode 100644 (file)
index 0000000..f98121c
Binary files /dev/null and b/src/maps/rooms/h1308.png differ
diff --git a/src/maps/rooms/h1309.png b/src/maps/rooms/h1309.png
new file mode 100644 (file)
index 0000000..34b608a
Binary files /dev/null and b/src/maps/rooms/h1309.png differ
diff --git a/src/maps/rooms/h2111.png b/src/maps/rooms/h2111.png
new file mode 100644 (file)
index 0000000..3d446b1
Binary files /dev/null and b/src/maps/rooms/h2111.png differ
diff --git a/src/maps/rooms/h2213.png b/src/maps/rooms/h2213.png
new file mode 100644 (file)
index 0000000..2e400dd
Binary files /dev/null and b/src/maps/rooms/h2213.png differ
diff --git a/src/maps/rooms/h2214.png b/src/maps/rooms/h2214.png
new file mode 100644 (file)
index 0000000..90018e2
Binary files /dev/null and b/src/maps/rooms/h2214.png differ
diff --git a/src/maps/rooms/infodesk.png b/src/maps/rooms/infodesk.png
new file mode 100644 (file)
index 0000000..8c392e9
Binary files /dev/null and b/src/maps/rooms/infodesk.png differ
diff --git a/src/maps/rooms/janson.png b/src/maps/rooms/janson.png
new file mode 100644 (file)
index 0000000..e5e7161
Binary files /dev/null and b/src/maps/rooms/janson.png differ
diff --git a/src/maps/rooms/lameere.png b/src/maps/rooms/lameere.png
new file mode 100644 (file)
index 0000000..2018cd5
Binary files /dev/null and b/src/maps/rooms/lameere.png differ
diff --git a/src/maps/rooms/not-available.png b/src/maps/rooms/not-available.png
new file mode 100644 (file)
index 0000000..ebfedad
Binary files /dev/null and b/src/maps/rooms/not-available.png differ
diff --git a/src/maps/rooms/thumbs/H-WC.png b/src/maps/rooms/thumbs/H-WC.png
new file mode 100644 (file)
index 0000000..0383264
Binary files /dev/null and b/src/maps/rooms/thumbs/H-WC.png differ
diff --git a/src/maps/rooms/thumbs/aw1105.png b/src/maps/rooms/thumbs/aw1105.png
new file mode 100644 (file)
index 0000000..aec3314
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1105.png differ
diff --git a/src/maps/rooms/thumbs/aw1115.png b/src/maps/rooms/thumbs/aw1115.png
new file mode 100644 (file)
index 0000000..e7a33a9
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1115.png differ
diff --git a/src/maps/rooms/thumbs/aw1117.png b/src/maps/rooms/thumbs/aw1117.png
new file mode 100644 (file)
index 0000000..95aeaae
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1117.png differ
diff --git a/src/maps/rooms/thumbs/aw1120.png b/src/maps/rooms/thumbs/aw1120.png
new file mode 100644 (file)
index 0000000..86513ea
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1120.png differ
diff --git a/src/maps/rooms/thumbs/aw1121.png b/src/maps/rooms/thumbs/aw1121.png
new file mode 100644 (file)
index 0000000..691bfd7
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1121.png differ
diff --git a/src/maps/rooms/thumbs/aw1124.png b/src/maps/rooms/thumbs/aw1124.png
new file mode 100644 (file)
index 0000000..1771b0e
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1124.png differ
diff --git a/src/maps/rooms/thumbs/aw1125.png b/src/maps/rooms/thumbs/aw1125.png
new file mode 100644 (file)
index 0000000..ae3746b
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1125.png differ
diff --git a/src/maps/rooms/thumbs/aw1126.png b/src/maps/rooms/thumbs/aw1126.png
new file mode 100644 (file)
index 0000000..395cd17
Binary files /dev/null and b/src/maps/rooms/thumbs/aw1126.png differ
diff --git a/src/maps/rooms/thumbs/chavanne.png b/src/maps/rooms/thumbs/chavanne.png
new file mode 100644 (file)
index 0000000..be23ef0
Binary files /dev/null and b/src/maps/rooms/thumbs/chavanne.png differ
diff --git a/src/maps/rooms/thumbs/ferrer.png b/src/maps/rooms/thumbs/ferrer.png
new file mode 100644 (file)
index 0000000..4c6704f
Binary files /dev/null and b/src/maps/rooms/thumbs/ferrer.png differ
diff --git a/src/maps/rooms/thumbs/guillissen.png b/src/maps/rooms/thumbs/guillissen.png
new file mode 100644 (file)
index 0000000..22b4ed3
Binary files /dev/null and b/src/maps/rooms/thumbs/guillissen.png differ
diff --git a/src/maps/rooms/thumbs/h1301.png b/src/maps/rooms/thumbs/h1301.png
new file mode 100644 (file)
index 0000000..7fc2915
Binary files /dev/null and b/src/maps/rooms/thumbs/h1301.png differ
diff --git a/src/maps/rooms/thumbs/h1302.png b/src/maps/rooms/thumbs/h1302.png
new file mode 100644 (file)
index 0000000..893fccc
Binary files /dev/null and b/src/maps/rooms/thumbs/h1302.png differ
diff --git a/src/maps/rooms/thumbs/h1308.png b/src/maps/rooms/thumbs/h1308.png
new file mode 100644 (file)
index 0000000..d6f9e42
Binary files /dev/null and b/src/maps/rooms/thumbs/h1308.png differ
diff --git a/src/maps/rooms/thumbs/h1309.png b/src/maps/rooms/thumbs/h1309.png
new file mode 100644 (file)
index 0000000..9086212
Binary files /dev/null and b/src/maps/rooms/thumbs/h1309.png differ
diff --git a/src/maps/rooms/thumbs/h2111.png b/src/maps/rooms/thumbs/h2111.png
new file mode 100644 (file)
index 0000000..07301cf
Binary files /dev/null and b/src/maps/rooms/thumbs/h2111.png differ
diff --git a/src/maps/rooms/thumbs/h2213.png b/src/maps/rooms/thumbs/h2213.png
new file mode 100644 (file)
index 0000000..ecf8d8c
Binary files /dev/null and b/src/maps/rooms/thumbs/h2213.png differ
diff --git a/src/maps/rooms/thumbs/h2214.png b/src/maps/rooms/thumbs/h2214.png
new file mode 100644 (file)
index 0000000..d1f6ca8
Binary files /dev/null and b/src/maps/rooms/thumbs/h2214.png differ
diff --git a/src/maps/rooms/thumbs/infodesk.png b/src/maps/rooms/thumbs/infodesk.png
new file mode 100644 (file)
index 0000000..a8250dd
Binary files /dev/null and b/src/maps/rooms/thumbs/infodesk.png differ
diff --git a/src/maps/rooms/thumbs/janson.png b/src/maps/rooms/thumbs/janson.png
new file mode 100644 (file)
index 0000000..28856b9
Binary files /dev/null and b/src/maps/rooms/thumbs/janson.png differ
diff --git a/src/maps/rooms/thumbs/lameere.png b/src/maps/rooms/thumbs/lameere.png
new file mode 100644 (file)
index 0000000..94d2b22
Binary files /dev/null and b/src/maps/rooms/thumbs/lameere.png differ
diff --git a/src/maps/rooms/ua2114.png b/src/maps/rooms/ua2114.png
new file mode 100644 (file)
index 0000000..1fcdae7
Binary files /dev/null and b/src/maps/rooms/ua2114.png differ
diff --git a/src/mvc/conference.cpp b/src/mvc/conference.cpp
new file mode 100644 (file)
index 0000000..b08a248
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "conference.h"
+
+QSqlRecord const Conference::sColumns = Conference::toRecord(QList<QSqlField>()
+    << QSqlField("id", QVariant::Int)
+    << QSqlField("title", QVariant::String)
+    << QSqlField("subtitle", QVariant::String)
+    << QSqlField("venue", QVariant::String)
+    << QSqlField("city", QVariant::String)
+    << QSqlField("start", QVariant::DateTime)
+    << QSqlField("end", QVariant::DateTime)
+    << QSqlField("days", QVariant::Int)
+    << QSqlField("day_change", QVariant::Int)
+    << QSqlField("timeslot_duration", QVariant::Int)
+    << QSqlField("active", QVariant::Bool));
+
+QString const Conference::sTableName = QString("conference");
+
+Conference Conference::getById(int id)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery() + "WHERE id = :id");
+    query.bindValue(":id", id);
+    return loadOne(query);
+}
+
+QList<Conference> Conference::getAll()
+{
+    QSqlQuery query;
+    query.prepare(selectQuery());
+    return load(query);
+}
+
+int Conference::activeConference()
+{
+    QSqlQuery query("SELECT id FROM conference WHERE active = 1");
+    query.exec();
+
+    QList<int> activeConfs;
+    while(query.next())
+        activeConfs.append(query.record().value("id").toInt());
+
+    if(activeConfs.count()==0) // no active DB
+        return 1;
+    else // even if there are more active confs, the first from the list is confidered active
+        return activeConfs[0];
+}
+
diff --git a/src/mvc/conference.h b/src/mvc/conference.h
new file mode 100644 (file)
index 0000000..d8b9318
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef CONFERENCE_H
+#define CONFERENCE_H
+
+#include <QDateTime>
+#include <QVector>
+#include <QStringList>
+
+#include <ormrecord.h>
+
+class Conference : public OrmRecord<Conference>
+{
+public:
+    static QSqlRecord const sColumns;
+    static QString const sTableName;
+
+public:
+    static Conference getById(int id);
+    static QList<Conference> getAll();
+    static int activeConference();
+
+public:
+    int id() const { return value("id").toInt(); }
+    QString title() const { return value("title").toString(); }
+    QString subtitle() const { return value("subtitle").toString(); }
+    QString venue() const { return value("venue").toString(); }
+    QString city() const { return value("city").toString(); }
+    QDate start() const { return value("start").toDate(); }
+    QDate end() const { return value("end").toDate(); }
+    int days() const { return value("days").toInt(); }
+    int dayChange() const { return value("day_change").toInt(); } // in seconds from 00:00
+    int timeslotDuration() const { return value("timeslot_duration").toInt(); } // in seconds
+    bool isActive() const { return value("active").toBool(); }
+
+    void setId(int id) { setValue("id", id); }
+    void setTitle(const QString& title) { setValue("title", title); }
+    void setSubtitle(const QString& subtitle) { setValue("subtitle", subtitle); }
+    void setVenue(const QString& venue) { setValue("venue", venue); }
+    void setCity(const QString& city) { setValue("city", city); }
+    void setStart(const QDate& start) { setValue("start", start); }
+    void setEnd(const QDate& end) { setValue("end", end); }
+    void setDays(int days) { setValue("days", days); }
+    void setDayChange(int dayChange) { setValue("day_change", dayChange); }
+    void setTimeslotDuration(int timeslotDuration) { setValue("timeslot_duration", timeslotDuration); }
+    void setActive(bool active) { setValue("active", (int)((active))); }
+};
+
+#endif /* CONFERENCE_H */
+
diff --git a/src/mvc/delegate.cpp b/src/mvc/delegate.cpp
new file mode 100644 (file)
index 0000000..ab0774f
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "delegate.h"
+#include "eventmodel.h"
+#include <track.h>
+
+#include <QDebug>
+#include <QPainter>
+
+const int RADIUS = 10;
+const int SPACER = 10;
+
+const double scaleFactor1 = 0.4;
+const double scaleFactor2 = 0.8;
+
+Delegate::Delegate(QTreeView *aParent)
+    : QItemDelegate(aParent)
+    , mViewPtr(aParent)
+{
+    mControls.clear();
+    defineControls();
+}
+
+Delegate::~Delegate()
+{
+    QListIterator<ControlId> i(mControls.keys());
+    while (i.hasNext())
+    {
+        delete mControls[i.next()]->image();
+    }
+}
+
+void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    if(!mViewPtr)
+        return;
+
+    painter->save();
+    QColor bkgrColor = Qt::cyan;
+    //QColor bkgrColor = QColor(0xAA,0xAA,0xAA);
+    QColor conflictColor = Qt::yellow;
+
+    QPen borderPen(bkgrColor.darker());
+    if(hasParent(index))
+    {
+        int aux = option.rect.height() - mControls[FavouriteControlOn]->drawPoint().y() - mControls[FavouriteControlOn]->image()->height();
+        // font SMALL
+        QFont fontSmall = option.font;
+        fontSmall.setBold(false);
+        fontSmall.setPixelSize(aux*0.2);
+        QFontMetrics fmSmall(fontSmall);
+        // font SMALL bold
+        QFont fontSmallB = fontSmall;
+        fontSmallB.setBold(true);
+        QFontMetrics fmSmallB(fontSmallB);
+
+        // font BIG
+        QFont fontBig = option.font;
+        fontBig.setBold(false);
+        fontBig.setPixelSize(aux*0.33);
+        QFontMetrics fmBig(fontBig);
+        // font BIG bold
+        QFont fontBigB = fontBig;
+        fontBigB.setBold(true);
+        QFontMetrics fmBigB(fontBigB);
+
+        //int spacer = (fmSmall.boundingRect("999").width() < SPACER) ? SPACER : fmSmall.boundingRect("999").width();
+
+        //Time conflicts are colored differently
+        if(static_cast<Event*>(index.internalPointer())->hasTimeConflict())
+            bkgrColor = conflictColor;
+
+        QLinearGradient itemGradient(option.rect.topLeft(), option.rect.bottomLeft());
+        itemGradient.setColorAt(0.0, Qt::white);
+        itemGradient.setColorAt(0.25, bkgrColor);
+        itemGradient.setColorAt(0.5, bkgrColor);
+        itemGradient.setColorAt(0.75, bkgrColor);
+        itemGradient.setColorAt(1.0, Qt::white);
+
+        if(isLast(index))
+        {
+            QPainterPath endPath;
+            endPath.moveTo(option.rect.topLeft());
+            endPath.lineTo(option.rect.bottomLeft()-QPoint(0, RADIUS));
+            endPath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 180, 90);
+            endPath.lineTo(option.rect.bottomRight()-QPoint(RADIUS, 0));
+            endPath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, 90);
+            endPath.lineTo(option.rect.topRight());
+
+            //painter->setBrush( bkgrColor );
+            painter->setBrush(itemGradient);
+            painter->setPen(borderPen);
+            painter->drawPath(endPath);
+
+            painter->setFont(option.font);
+        }
+        else // middle elements
+        {
+            //painter->setBrush( bkgrColor );
+            painter->setBrush(itemGradient);
+            painter->setPen(Qt::NoPen);
+            painter->drawRect(option.rect);
+
+            painter->setPen(borderPen);
+            // vertical lines
+            painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
+            painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
+            // horizontal lines
+            painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
+
+            painter->setFont(option.font);
+        }
+
+        // draw Controls
+        // favourite
+        if(static_cast<Event*>(index.internalPointer())->isFavourite())
+            painter->drawImage(mControls[FavouriteControlOn]->drawPoint(option.rect),*mControls[FavouriteControlOn]->image());
+        else
+            painter->drawImage(mControls[FavouriteControlOff]->drawPoint(option.rect),*mControls[FavouriteControlOff]->image());
+#ifdef MAEMO
+        // alarm
+        if(static_cast<Event*>(index.internalPointer())->hasAlarm())
+            painter->drawImage(mControls[AlarmControlOn]->drawPoint(option.rect),*mControls[AlarmControlOn]->image());
+        else
+            painter->drawImage(mControls[AlarmControlOff]->drawPoint(option.rect),*mControls[AlarmControlOff]->image());
+#endif
+        // map
+        painter->drawImage(mControls[MapControl]->drawPoint(option.rect),*mControls[MapControl]->image());
+        // Time conflict
+        if(static_cast<Event*>(index.internalPointer())->hasTimeConflict())
+            painter->drawImage(mControls[WarningControl]->drawPoint(option.rect),*mControls[WarningControl]->image());
+
+        // draw texts
+        Event *event = static_cast<Event*>(index.internalPointer());
+        QPointF titlePointF(mControls[FavouriteControlOn]->drawPoint(option.rect));
+        titlePointF.setX(option.rect.x()+SPACER);
+        titlePointF.setY(titlePointF.y()+mControls[FavouriteControlOn]->image()->height());
+        QTime start = event->start().time();
+        painter->setFont(fontBig);
+        painter->drawText(titlePointF,start.toString("hh:mm") + "-" + start.addSecs(event->duration()).toString("hh:mm") + ", " + event->room());
+        // title
+        titlePointF.setY(titlePointF.y()+fmBig.height()-fmBig.descent());
+        painter->setFont(fontBigB);
+        QString title = event->title();
+        if(fmBigB.boundingRect(title).width() > (option.rect.width()-2*SPACER)) // the title won't fit the screen
+        {
+            // chop words from the end
+            while( (fmBigB.boundingRect(title + "...").width() > (option.rect.width()-2*SPACER)) && !title.isEmpty())
+            {
+                title.chop(1);
+                // chop characters one-by-one from the end
+                while( (!title.at(title.length()-1).isSpace()) && !title.isEmpty())
+                {
+                    title.chop(1);
+                }
+            }
+            title += "...";
+        }
+        painter->drawText(titlePointF,title);
+        // persons
+        titlePointF.setY(titlePointF.y()+fmSmall.height()-fmSmall.descent());
+        painter->setFont(fontSmall);
+        painter->drawText(titlePointF,"Presenter(s): " + event->persons().join(" and "));
+        // track
+        titlePointF.setY(titlePointF.y()+fmSmall.height()-fmSmall.descent());
+        painter->drawText(titlePointF,"Track: " + Track::retrieveTrackName(event->trackId()));
+    }
+    else // doesn't have parent - time-groups' elements (top items)
+    {
+        QFont fontSmall = option.font;
+        fontSmall.setBold(true);
+        fontSmall.setPixelSize(option.rect.height()*scaleFactor1);
+        QFontMetrics fmSmall(fontSmall);
+
+        QFont fontBig = option.font;
+        fontBig.setBold(true);
+        fontBig.setPixelSize(option.rect.height()*scaleFactor2);
+        QFontMetrics fmBig(fontBig);
+
+        int spacer = (fmSmall.boundingRect("999").width() < SPACER) ? SPACER : fmSmall.boundingRect("999").width();
+
+        QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
+        //titleGradient.setColorAt(0.0, Qt::white);
+        titleGradient.setColorAt(0.0, bkgrColor);
+        titleGradient.setColorAt(0.5, Qt::white);
+        titleGradient.setColorAt(1.0, bkgrColor);
+
+        QPainterPath titlePath;
+        if(isExpanded(index))
+        {
+            titlePath.moveTo(option.rect.bottomLeft());
+            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
+            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
+            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
+            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
+            titlePath.lineTo(option.rect.bottomRight());
+            titlePath.closeSubpath();
+        }
+        else
+        {
+            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
+            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
+            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
+            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
+            titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
+            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
+            titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
+            titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);      
+            titlePath.closeSubpath();
+        }
+
+        painter->setBrush(titleGradient);
+        painter->setPen(borderPen);
+        painter->drawPath(titlePath);
+
+        // draw icons 
+        painter->setFont(fontSmall);
+        QImage *image = mControls[FavouriteControlOn]->image();
+        QPoint drawPoint =
+            option.rect.topRight()
+            - QPoint(
+                    spacer + image->width(),
+                    - option.rect.height()/2 + image->height()/2);
+        painter->drawImage(drawPoint,*image);
+        painter->drawText(drawPoint+QPoint(image->width()+2, image->height() - 2),
+                QString::number(numberOfFavourities(index)));
+#ifdef MAEMO
+        drawPoint.setX(drawPoint.x() - spacer - image->width());
+        painter->drawImage(drawPoint,*mControls[AlarmControlOn]->image());
+        painter->drawText(drawPoint+QPoint(image->width()+2, image->height() - 2),
+                QString::number(numberOfAlarms(index)));
+#endif
+        // draw texts
+        QString numEvents = QString::number(index.model()->rowCount(index)).append("/");
+        drawPoint.setX(drawPoint.x() - spacer - fmSmall.boundingRect(numEvents).width());
+        drawPoint.setY(drawPoint.y()+image->height() - 2);
+        painter->drawText(drawPoint,numEvents);
+
+        QPointF titlePointF = QPoint(
+                option.rect.x()+SPACER,
+                option.rect.y()+option.rect.height()-fmBig.descent());
+        painter->setFont(fontBig);
+
+        painter->drawText(titlePointF,qVariantValue<QString>(index.data()));
+    }
+
+    //// HIGHLIGHTING SELECTED ITEM
+    //if (option.state & QStyle::State_Selected)
+        //painter->fillRect(option.rect, option.palette.highlight());
+
+    painter->restore();
+}
+
+QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    Q_UNUSED(option)
+
+    if (index.internalId() == 0) // time group
+    {
+        return QSize(40,40);
+    }
+    else // event
+    {
+        return QSize(100,100);
+    }
+}
+
+bool Delegate::hasParent( const QModelIndex &index ) const
+{
+    if( index.parent().isValid() )
+        return true;
+    else
+        return false;
+}
+  
+bool Delegate::isLast( const QModelIndex &index ) const
+{
+    if(!hasParent(index))
+        return false; // what should be returned here?
+
+    if(index.row() >= (index.model()->rowCount(index.parent())-1))
+        return true;
+    else
+        return false;
+}
+
+bool Delegate::isExpanded( const QModelIndex &index ) const
+{
+    if( !mViewPtr )
+        return false;
+    else
+        return mViewPtr->isExpanded( index );
+}
+
+Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
+{
+    if(!hasParent(aIndex)) // time-group item (root item)
+        return ControlNone;
+
+    QListIterator<ControlId> i(mControls.keys());
+    while (i.hasNext())
+    {
+        ControlId id = i.next();
+        if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
+        {
+            if(id == WarningControl)
+            {
+                if(static_cast<Event*>(aIndex.internalPointer())->hasTimeConflict())
+                    return id;
+            }
+            else
+                return id;
+        }
+    }
+
+    return ControlNone;
+}
+
+void Delegate::defineControls()
+{
+    Control *control;
+    QPoint p(0,0);
+    // FAVOURITE ICONs
+    // on
+    control = new Control(FavouriteControlOn,QString(":icons/favourite-onBig.png"));
+    p = QPoint(0,SPACER);
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(FavouriteControlOn,control);
+    // off
+    control = new Control(FavouriteControlOff,QString(":icons/favourite-offBig.png"));
+    p = QPoint(0,SPACER);
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(FavouriteControlOff,control);
+
+#ifdef MAEMO
+    // ALARM ICONs
+    // on
+    control = new Control(AlarmControlOn,QString(":icons/alarm-onBig.png"));
+    p = mControls[FavouriteControlOn]->drawPoint();
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(AlarmControlOn,control);
+    // off
+    control = new Control(AlarmControlOff,QString(":icons/alarm-offBig.png"));
+    p = mControls[FavouriteControlOff]->drawPoint();
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(AlarmControlOff,control);
+
+    // MAP ICON
+    control = new Control(MapControl,QString(":icons/compassBig.png"));
+    p = mControls[AlarmControlOn]->drawPoint();
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(MapControl,control);
+#else
+    // MAP ICON
+    control = new Control(MapControl,QString(":icons/compassBig.png"));
+    p = mControls[FavouriteControlOn]->drawPoint();
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(MapControl,control);
+#endif
+
+    // WARNING ICON
+    control = new Control(WarningControl,QString(":icons/exclamation.png"));
+    p = mControls[MapControl]->drawPoint();
+    p.setX(p.x()-control->image()->width()-SPACER);
+    control->setDrawPoint(p);
+    mControls.insert(WarningControl,control);
+}
+
+bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
+{
+    if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
+        return true;
+
+    return false;
+}
+
+int Delegate::numberOfFavourities(const QModelIndex &index) const
+{
+    if(index.parent().isValid()) // it's event, not time-group
+        return 0;
+
+    int nrofFavs = 0;
+    for(int i=0; i<index.model()->rowCount(index); i++)
+        if(static_cast<Event*>(index.child(i,0).internalPointer())->isFavourite())
+            nrofFavs++;
+
+    return nrofFavs;
+}
+
+int Delegate::numberOfAlarms(const QModelIndex &index) const
+{
+    if(index.parent().isValid()) // it's event, not time-group
+        return 0;
+
+    int nrofAlarms = 0;
+    for(int i=0; i<index.model()->rowCount(index); i++)
+        if(static_cast<Event*>(index.child(i,0).internalPointer())->hasAlarm())
+            nrofAlarms++;
+
+    return nrofAlarms;
+}
+
diff --git a/src/mvc/delegate.h b/src/mvc/delegate.h
new file mode 100644 (file)
index 0000000..227cccc
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef DELEGATE_H
+#define DELEGATE_H
+
+#include <QItemDelegate>
+#include <QTreeView>
+#include <QPointer>
+
+class Delegate : public QItemDelegate
+{
+    Q_OBJECT
+
+    public:
+
+        enum ControlId
+        {
+            ControlNone = 0,
+            FavouriteControlOn,
+            FavouriteControlOff,
+            AlarmControlOn,
+            AlarmControlOff,
+            MapControl,
+            WarningControl
+        };
+
+        class Control
+        {
+            public:
+                Control(ControlId aControlId, const QString &aImageName)
+                    : mId(aControlId)
+                    , mImage(new QImage(aImageName))
+                    , mDrawPoint(QPoint(0,0))
+                { }
+                inline QImage *image() const { return mImage; }
+                inline void setDrawPoint(const QPoint &aPoint) { mDrawPoint = aPoint; }
+                inline QPoint drawPoint(const QRect &aRect = QRect()) const // for painter to draw Control
+                {
+                    if(aRect == QRect()) // null rectangle
+                        return mDrawPoint; // returns relative drawing point
+                    else
+                        return QPoint(aRect.x()+aRect.width(),aRect.y()) + mDrawPoint; // returns absolute drawing point
+                }
+                inline QRect drawRect(const QRect &aRect) const // helper for determining if Control was clicked
+                {
+                    return QRect(drawPoint(aRect), drawPoint(aRect)+QPoint(mImage->size().width(),mImage->size().height()));
+                }
+            private:
+                ControlId mId;
+                QImage *mImage;
+                QPoint mDrawPoint; // relative 'start-drawing' position (may hold negative values)
+        };
+
+        Delegate(QTreeView *aParent); // the delegate 'owner' has to be specified in the constructor - it's used to obtain visualRect of selected item/index
+        ~Delegate();
+
+        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+        //
+        Delegate::ControlId whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const;
+        bool isPointFromRect(const QPoint &aPoint, const QRect &aRect) const;
+
+    private:
+        bool hasParent( const QModelIndex &index ) const;
+        bool isLast( const QModelIndex &index ) const;
+        bool isExpanded( const QModelIndex &index ) const;
+        void defineControls();
+        // TODO: the better place for these methods would be 'eventmodel'
+        // they are used in 'paint' method and so it's better to obtain number of
+        // favourities/alarms once when the data has changed and not to call
+        // these methods which iterate over all Events in corresponding group
+        // every time it requires them
+        int numberOfFavourities(const QModelIndex &index) const;
+        int numberOfAlarms(const QModelIndex &index) const;
+
+    private:
+        QPointer<QTreeView> mViewPtr;
+        QMap<ControlId,Control*> mControls;
+};
+
+#endif /* DELEGATE_H */
+
diff --git a/src/mvc/event.cpp b/src/mvc/event.cpp
new file mode 100644 (file)
index 0000000..cf0a2bd
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "event.h"
+#include "room.h"
+
+QString const Event::sTableName = QString("event");
+
+QSqlRecord const Event::sColumns = Event::toRecord(QList<QSqlField>()
+    << QSqlField("id", QVariant::Int)
+    << QSqlField("xid_conference", QVariant::Int)
+    << QSqlField("start", QVariant::DateTime)
+    << QSqlField("duration", QVariant::Int)
+    << QSqlField("xid_track", QVariant::Int)
+    << QSqlField("type", QVariant::String)
+    << QSqlField("language", QVariant::String)
+    << QSqlField("favourite", QVariant::Bool)
+    << QSqlField("alarm", QVariant::Bool)
+    << QSqlField("tag", QVariant::String)
+    << QSqlField("title", QVariant::String)
+    << QSqlField("subtitle", QVariant::String)
+    << QSqlField("abstract", QVariant::String)
+    << QSqlField("description", QVariant::String));
+
+Event::Event() :
+    mRoomId( 0 )
+{
+}
+
+Event Event::getById(int id, int conferenceId)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery() + "WHERE id = :id AND xid_conference = :conf");
+    query.bindValue(":id", id);
+    query.bindValue(":conf", conferenceId);
+    return loadOne(query);
+}
+
+QList<Event> Event::getByDate(const QDate& date, int conferenceId, QString orderBy)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery() + QString("WHERE xid_conference = :conf AND start >= :start AND start < :end ORDER BY %1").arg(orderBy));
+    query.bindValue(":conf", conferenceId);
+    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
+    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+
+    return load(query);
+}
+
+QList<Event> Event::getByDateAndRoom(const QDate& date, int conferenceId)
+{
+    QSqlQuery query;
+    QString aliasEvent("E");
+    QString aliasEventRoom("R");
+    query.prepare(QString("SELECT %1 FROM %2 %3, %4 %5 WHERE %3.xid_conference = :conf AND %3.start >= :start AND %3.start < :end AND %3.id = R.xid_event ORDER BY %5.xid_room, %3.start").arg(
+                    columnsForSelect(aliasEvent), Event::sTableName, aliasEvent, "EVENT_ROOM", aliasEventRoom));
+    query.bindValue(":conf", conferenceId);
+    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
+    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+
+    return load(query);
+}
+
+QList<Event> Event::nowEvents(int conferenceId, QString orderBy)
+{
+    uint curTime_t =  QDateTime(QDate::currentDate(),QTime::currentTime(),Qt::UTC).toTime_t();
+    //uint curTime_t = 1265457610; // for testing
+
+    QSqlQuery query;
+    query.prepare(selectQuery() + QString("WHERE xid_conference = :conf AND start <= :now1 AND ( start + duration ) > :now2 ORDER BY %1").arg(orderBy));
+    query.bindValue(":conf", conferenceId);
+    query.bindValue(":now1", convertToDb(curTime_t, QVariant::DateTime));
+    query.bindValue(":now2", convertToDb(curTime_t, QVariant::DateTime));
+
+    return load(query);
+}
+
+QList<Event> Event::conflictEvents(int aEventId, int conferenceId)
+{
+    QSqlQuery query;
+    Event event = Event::getById(aEventId,conferenceId);
+    query.prepare(selectQuery() + "WHERE xid_conference = :conf AND ( \
+           ( start >= :s1 AND ( start + duration ) < :e1 ) \
+        OR ( ( start + duration ) > :s2 AND start < :e2 ) ) \
+        AND favourite = 1 AND NOT id = :id ORDER BY start");
+    query.bindValue(":conf", event.conferenceId());
+    query.bindValue(":s1", convertToDb(event.start(), QVariant::DateTime));
+    query.bindValue(":e1", convertToDb(event.start().toTime_t()+event.duration(), QVariant::DateTime));
+    query.bindValue(":s2", convertToDb(event.start(), QVariant::DateTime));
+    query.bindValue(":e2", convertToDb(event.start().toTime_t()+event.duration(), QVariant::DateTime));
+    query.bindValue(":id", event.id());
+
+    return load(query);
+}
+
+QList<Event> Event::getFavByDate(const QDate& date, int conferenceId)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery() + QString("WHERE xid_conference = :conf AND start >= :start AND start < :end AND favourite = 1 ORDER BY start"));
+    query.bindValue(":conf", conferenceId);
+    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
+    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+
+    return load(query);
+}
+
+QString Event::room()
+{
+    if ( mRoomName.isEmpty() )
+    {
+        QSqlQuery query;
+        // TODO: conference ID isn't used here
+        query.prepare("SELECT name FROM room WHERE id = :roomId");
+        query.bindValue(":roomId", roomId());
+        query.exec();
+        // TODO: handle qeury error
+        //qDebug() << query.lastError();
+        if(query.next())
+            mRoomName = query.record().value("name").toString();
+        else
+            mRoomName = QString("not-available");
+    }
+    return mRoomName;
+}
+
+int Event::roomId()
+{
+    if ( mRoomId == 0 )
+    {
+        QSqlQuery query;
+        query.prepare("SELECT xid_room FROM event_room WHERE xid_event = :id");
+        query.bindValue(":id", id());
+        if (!query.isActive())
+            if (!query.exec())
+                throw OrmSqlException(query.lastError().text());
+        if (!query.next())
+        {
+            qDebug() << "No room found for event id: " << id();
+            throw OrmNoObjectException();
+        }
+        mRoomId = query.record().value("xid_room").toInt();
+    }
+    return mRoomId;
+}
+
+QStringList Event::persons()
+{
+    if( mPersonsList.isEmpty() )
+    {
+        QSqlQuery query;
+        // TODO: conference ID isn't used here
+        query.prepare("SELECT person.name FROM person INNER JOIN event_person ON person.id = event_person.xid_person AND event_person.xid_event = :id");
+        query.bindValue(":id", id());
+        query.exec();
+        // TODO: handle qeury error
+        //qDebug() << query.lastError();
+
+        while(query.next())
+            mPersonsList.append(query.record().value("name").toString());
+    }
+
+    return mPersonsList;
+}
+
+QMap<QString,QString> Event::links()
+{
+    if ( mLinksList.isEmpty() )
+    {
+        QSqlQuery query;
+        query.prepare("SELECT name,url FROM link WHERE xid_event = :id AND xid_conference = :conf");
+        query.bindValue(":id", id());
+        query.bindValue(":conf", conferenceId());
+        query.exec();
+        // TODO: handle qeury error
+        //qDebug() << query.lastError();
+
+        while(query.next())
+            mLinksList.insert(query.record().value("name").toString(), query.record().value("url").toString());
+    }
+    return mLinksList;
+}
+
+bool Event::hasTimeConflict() const
+{
+    if(!isFavourite()) // if it's not favourite, it can't have time-conflict
+        return false;
+
+    return conflictEvents(id(),conferenceId()).count() > 0 ? true : false;
+}
+
+void Event::setRoom(const QString &room)
+{
+    Q_UNUSED(room);
+
+    qWarning("WARINING: setRoom() is NOT IMPLEMENTED YET");
+    // TODO: implement
+}
+
+void Event::setPersons(const QStringList &persons)
+{
+    Q_UNUSED(persons);
+
+    qWarning("WARINING: setPersons() is NOT IMPLEMENTED YET");
+    // TODO: implement
+}
+
+void Event::setLinks(const QMap<QString,QString> &aLinks)
+{
+    Q_UNUSED(aLinks);
+
+    qWarning("WARINING: setLinks() is NOT IMPLEMENTED YET");
+    // TODO: implement
+}
+
+QList<Event> Event::getSearchResultByDate(const QDate& date, int conferenceId, QString orderBy)
+{
+    QString strQuery = QString("SELECT %1 FROM EVENT INNER JOIN SEARCH_EVENT USING (xid_conference, id) ").arg(columnsForSelect());
+    strQuery += QString("WHERE xid_conference = :conf AND start >= :start AND start < :end ORDER BY %1").arg(orderBy);
+    //qDebug() << strQuery;
+    QList<Event> list;
+    QSqlQuery query;
+    try{
+        if( !query.prepare( strQuery ) ){
+            qDebug() << "QSqlQuery.prepare error";
+            throw OrmSqlException( query.lastError().text() );
+        }
+
+        query.bindValue(":conf", conferenceId);
+        query.bindValue(":start", convertToDb(date, QVariant::DateTime));
+        query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+
+        list = load(query);
+    }
+    catch(OrmException &e)
+    {
+        qDebug() << "getSearchResultByDate error: " << e.text();
+    }
+    catch(...){
+        qDebug() << "getSearchResultByDate failed ...";
+    }
+    return list;
+}
+
diff --git a/src/mvc/event.h b/src/mvc/event.h
new file mode 100644 (file)
index 0000000..a4a73f0
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <QDateTime>
+#include <QVector>
+#include <QStringList>
+
+#include <ormrecord.h>
+
+/**
+  NoSuchEventException is thrown when required event does not exist.
+*/
+class NoSuchEventException
+{
+};
+
+class Event : public OrmRecord<Event>
+{
+public:
+    Event();
+    static const QSqlRecord sColumns;
+    static QString const sTableName;
+public:
+    static Event getById(int id, int conferenceId);
+    static QList<Event> getByDate(const QDate & date, int conferenceId, QString orderBy);
+    static QList<Event> getFavByDate(const QDate & date, int conferenceId); // get Favourities by Date
+    static QList<Event> getSearchResultByDate(const QDate& date, int conferenceId, QString orderBy);
+    static QList<Event> nowEvents(int conferenceId, QString orderBy); // get events scheduled NOW
+    static QList<Event> getByTrack(int id);
+    static QList<Event> getByDateAndRoom(const QDate& date, int conferenceId);
+    static QList<Event> conflictEvents(int aEventId, int conferenceId);
+public:
+    int id() const { return value("id").toInt(); }
+    int conferenceId() const { return value("xid_conference").toInt(); }
+    QDateTime start() const { return value("start").toDateTime(); }
+    int duration() const { return value("duration").toInt(); }
+    int trackId() const { return value("xid_track").toInt(); }
+    QString type() const { return value("type").toString(); }
+    QString language() const { return value("language").toString(); }
+    bool isFavourite() const { return value("favourite").toBool(); }
+    bool hasAlarm() const { return value("alarm").toBool(); }
+    bool hasTimeConflict() const;
+    QString tag() const { return value("tag").toString(); }
+    QString title() const { return value("title").toString(); }
+    QString subtitle() const { return value("subtitle").toString(); }
+    QString abstract() const { return value("abstract").toString(); }
+    QString description() const { return value("description").toString(); }
+    // records from other tables associated with 'id'
+    QString room();
+    int roomId();
+    QStringList persons();
+    QMap<QString,QString> links();
+
+    void setId(int id) { setValue("id", id); }
+    void setConferenceId(int conferenceId) { setValue("xid_conference", conferenceId); }
+    void setStart(const QDateTime & start) { setValue("start", start); }
+    void setDuration(int duration) { setValue("duration", duration); }
+    void setTrackId(int trackId) { setValue("xid_track", trackId); }
+    void setType(const QString & type) { setValue("type", type); }
+    void setLanguage(const QString & language) { setValue("language", language); }
+    void setFavourite(bool favourite) { setValue("favourite", (int)((favourite))); }
+    void setHasAlarm(bool alarm) { setValue("alarm", (int)((alarm))); }
+    void setTag(const QString& tag) { setValue("tag", tag); }
+    void setTitle(const QString& title) { setValue("title", title); }
+    void setSubtitle(const QString& subtitle) { setValue("subtitle", subtitle); }
+    void setAbstract(const QString& abstract) { setValue("abstract", abstract); }
+    void setDescription(const QString& description) { setValue("description", description); }
+    // records from other tables associated with 'id'
+    void setRoom(const QString& room);
+    void setPersons(const QStringList &persons);
+    void setLinks(const QMap<QString,QString> &aLinks);
+
+friend class EventTest;
+
+private:
+    QStringList mPersonsList;
+    QMap<QString,QString> mLinksList;
+    int mRoomId;
+    QString mRoomName;
+};
+
+#endif // EVENT_H
+
diff --git a/src/mvc/eventmodel.cpp b/src/mvc/eventmodel.cpp
new file mode 100644 (file)
index 0000000..a9cca04
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "eventmodel.h"
+#include <conference.h>
+#include <track.h>
+#include <room.h>
+
+const QString EventModel::COMMA_SEPARATOR = ", ";
+
+EventModel::EventModel()
+{
+    mEvents.clear();
+}
+
+void EventModel::createTimeGroups()
+{
+    mGroups.clear();
+    mParents.clear();
+
+    if (mEvents.empty())
+    {
+        return;
+    }
+
+    const int timeSpan = 5400;
+
+    QTime startTime = mEvents.first().start().time();
+    mGroups << EventModel::Group(QString("%1 - %2").arg(startTime.toString("HH:mm"),
+        startTime.addSecs(timeSpan).toString("HH:mm")), 0);
+    QTime nextGroupTime = mEvents.first().start().time().addSecs(timeSpan);
+
+    for (int i=0; i<mEvents.count(); i++)
+    {
+        QTime eventTime = mEvents.at(i).start().time();
+
+        if (nextGroupTime <= eventTime)
+        {
+            mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
+            mGroups << EventModel::Group(QString("%1 - %2").arg(nextGroupTime.toString("HH:mm"),
+                nextGroupTime.addSecs(timeSpan).toString("HH:mm")), i);
+            nextGroupTime = nextGroupTime.addSecs(timeSpan);
+        }
+
+        // add parent-child relation
+        mParents[mEvents.at(i).id()] = mGroups.count() - 1;
+    }
+
+    mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
+}
+
+void EventModel::createTrackGroups() {
+    mGroups.clear();
+    mParents.clear();
+    if (mEvents.empty())
+    {
+        return;
+    }
+    int trackId = mEvents.first().trackId();
+
+    mGroups << EventModel::Group(Track::retrieveTrackName(trackId), 0);
+    int nextTrackId = trackId;
+
+    for (int i=0; i<mEvents.count(); i++)
+    {
+        trackId = mEvents.at(i).trackId();
+        if (nextTrackId != trackId)
+        {
+            mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
+            mGroups << EventModel::Group(Track::retrieveTrackName(trackId), i);
+            nextTrackId = trackId;
+        }
+        // add parent-child relation
+        mParents[mEvents.at(i).id()] = mGroups.count() - 1;
+    }
+    mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
+}
+
+void EventModel::createRoomGroups()
+{
+    mGroups.clear();
+    mParents.clear();
+    if (mEvents.empty())
+    {
+        return;
+    }
+    int roomId = mEvents.first().roomId();
+
+    mGroups << EventModel::Group(Room::retrieveRoomName(roomId), 0);
+    int nextRoomId = roomId;
+
+    QList<Event>::iterator event = mEvents.begin();
+    int i = 0;
+    while (event != mEvents.end())
+    {
+        roomId = event->roomId();
+        if (nextRoomId != roomId)
+        {
+            mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
+            mGroups << EventModel::Group(Room::retrieveRoomName(roomId), i);
+            nextRoomId = roomId;
+        }
+        mParents[event->id()] = mGroups.count() - 1;
+        event++;
+        i++;
+    }
+    mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
+}
+
+QVariant EventModel::data(const QModelIndex& index, int role) const
+{
+    if (index.isValid() && role == Qt::DisplayRole)
+    {
+        if (index.internalId() == 0)
+        {
+            return mGroups.at(index.row()).mTitle;
+        }
+        else //event data
+        {
+            return static_cast<Event*>(index.internalPointer())->id();
+        }
+    }
+
+    return QVariant();
+}
+
+QModelIndex EventModel::index(int row, int column, const QModelIndex& parent) const
+{
+    // TODO: add checks for out of range rows
+
+    if (!parent.isValid())
+    {
+        return createIndex(row, column, 0);
+    }
+    else if (parent.internalId() == 0)
+    {
+        const Group& group = mGroups.at(parent.row());
+        Event* event = const_cast<Event*>(&mEvents.at(row + group.mFirstEventIndex));
+        return createIndex(row, column, reinterpret_cast<void*>(event));
+    }
+    else
+    {
+        return QModelIndex();
+    }
+}
+
+QModelIndex EventModel::parent(const QModelIndex & index) const
+{
+    if (index.isValid())
+    {
+        if (index.internalId() == 0)
+        {
+            return QModelIndex();
+        }
+
+        Event * event = static_cast<Event*>(index.internalPointer());
+
+        return createIndex(mParents[event->id()], 0, 0);
+    }
+
+    return QModelIndex();
+}
+
+int EventModel::columnCount(const QModelIndex & parent) const
+{
+    Q_UNUSED(parent);
+    return 1;
+}
+
+int EventModel::rowCount (const QModelIndex & parent) const
+{
+    if (!parent.isValid())
+    {
+        return mGroups.count();
+    }
+
+    if (parent.internalId() == 0)
+    {
+        return mGroups.at(parent.row()).mChildCount;
+    }
+
+    return 0;
+}
+
+void EventModel::clearModel()
+{
+    for(int i = 0;i < mGroups.count();i++){
+        QModelIndex idx = index(i, 0);
+        Group group = mGroups[i];
+        beginRemoveRows(idx, 0, group.mChildCount - 1);
+        /*bool ok =*/ removeRows(0, group.mChildCount, idx);
+        endRemoveRows();
+        //qDebug() << "removing " << group.mChildCount << " events from group:" << i << idx.data() << ":" << ok;
+    }
+    mEvents.clear();
+}
+
+void EventModel::loadEvents(const QDate &aDate, int aConferenceId)
+{
+    clearModel();
+    // check for existence of the conference in the DB
+    if(Conference::getAll().count())
+    {
+        qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
+        mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start");
+    }
+    createTimeGroups();
+}
+
+void EventModel::loadFavEvents(const QDate &aDate, int aConferenceId)
+{
+    clearModel();
+    // check for existence of the conference in the DB
+    if(Conference::getAll().count())
+    {
+        qDebug() << "Loading FAV Conference Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
+        mEvents = Event::getFavByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
+    }
+    createTimeGroups();
+}
+
+int EventModel::loadSearchResultEvents(const QDate &aDate, int aConferenceId)
+{
+    clearModel();
+    // check for existence of the conference in the DB
+    if(Conference::getAll().count())
+    {
+        qDebug() << "Loading search result Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
+        try{
+            mEvents = Event::getSearchResultByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start");
+        }
+        catch( OrmException &e  ){
+            qDebug() << "Event::getSearchResultByDate failed: " << e.text();
+        }
+        catch(...){
+            qDebug() << "Event::getSearchResultByDate failed";
+        }
+
+    }
+
+    createTimeGroups();
+
+    return mEvents.count();
+}
+
+void EventModel::loadEventsByTrack(const QDate &aDate, int aConferenceId)
+{
+    clearModel();
+    if (Conference::getAll().count())
+    {
+        qDebug() << "Loading Conference Data (by Track): [" << Conference::getById(aConferenceId).title() << "] " << aDate;
+        mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "xid_track, start");
+    }
+    createTrackGroups();
+}
+
+void EventModel::loadEventsByRoom(const QDate &aDate, int aConferenceId)
+{
+    clearModel();
+    if (Conference::getAll().count())
+    {
+        qDebug() << "Loading Conference Data (by Room): [" << Conference::getById(aConferenceId).title() << "] " << aDate;
+        mEvents = Event::getByDateAndRoom(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
+    }
+    createRoomGroups();
+}
+
+void EventModel::loadNowEvents(int aConferenceId)
+{
+    clearModel();
+    // check for existence of the conference in the DB
+    if(Conference::getAll().count())
+    {
+        qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] scheduled NOW";
+        mEvents = Event::nowEvents(aConferenceId, "start");
+    }
+    createTimeGroups();
+}
+
+void EventModel::loadConflictEvents(int aEventId, int aConferenceId)
+{
+    clearModel();
+    // check for existence of the conference in the DB
+    if(Conference::getAll().count())
+    {
+        qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] in conflict with " << aEventId;
+        mEvents = Event::conflictEvents(aEventId, aConferenceId);
+    }
+    createTimeGroups();
+}
+
+void EventModel::updateModel(int aEventId)
+{
+    for(int i=0; i<mEvents.count(); i++)
+    {
+        if(mEvents[i].id() == aEventId)
+            mEvents[i] = Event::getById(aEventId,Conference::activeConference());
+    }
+
+    // find the ModelIndex for given aEventId
+    for(int i=0; i<mGroups.count(); i++)
+    {
+        QModelIndex groupIndex = index(i,0,QModelIndex());
+        for(int j=0; j<mGroups[i].mChildCount; j++)
+        {
+            QModelIndex eventIndex = index(j,0,groupIndex);
+            if(static_cast<Event*>(eventIndex.internalPointer())->id() == aEventId)
+            {
+                emit(dataChanged(groupIndex,groupIndex));
+                emit(dataChanged(eventIndex,eventIndex));
+            }
+        }
+    }
+}
+
diff --git a/src/mvc/eventmodel.h b/src/mvc/eventmodel.h
new file mode 100644 (file)
index 0000000..9e90ec4
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef EVENTMODEL_H
+#define EVENTMODEL_H
+
+#include <QAbstractItemModel>
+
+#include "event.h"
+
+class EventModel : public QAbstractItemModel
+{
+public:
+    static const QString COMMA_SEPARATOR;
+public:
+    EventModel();
+    QVariant data(const QModelIndex& index, int role) const;
+    QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+    QModelIndex parent ( const QModelIndex & index ) const;
+    int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
+    int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
+    void loadEvents(const QDate &aDate, int aConferenceId); // loads Events from the DB
+    void loadFavEvents(const QDate &aDate, int aConferenceId); // loads Favourite events from the DB
+    void loadEventsByTrack(const QDate &aDate, int aConferenceId); // loads Events sorted by Track id and Event start from the DB
+    int loadSearchResultEvents(const QDate &aDate, int aConferenceId);
+    void loadNowEvents(int aConferenceId); // loads Now events from the DB
+    void loadEventsByRoom(const QDate &aDate, int aConferenceId);
+    void loadConflictEvents(int aEventId, int aConferenceId); // loads events in conflict
+
+private:
+    struct Group
+    {
+        Group(const QString & title,
+              int firstEventIndex) :
+
+            mTitle(title),
+            mFirstEventIndex(firstEventIndex),
+            mChildCount(0)
+        {}
+
+        QString mTitle;
+        int mFirstEventIndex;
+        int mChildCount;
+    };
+
+private:
+    void createTimeGroups();
+    void createTrackGroups();
+    void createTrackGroupsNew();
+    void clearModel();
+    void createRoomGroups();
+
+public slots:
+    void updateModel(int aEventId);
+
+private:
+    QList<Event> mEvents;
+    QList<Group> mGroups;
+    QHash<int, int> mParents;
+};
+
+#endif // EVENTMODEL_H
+
diff --git a/src/mvc/mvc.pro b/src/mvc/mvc.pro
new file mode 100644 (file)
index 0000000..53c0973
--- /dev/null
@@ -0,0 +1,36 @@
+include(../global.pri)
+TEMPLATE = lib
+TARGET = mvc
+DESTDIR = ../bin
+CONFIG += static
+QT += sql 
+
+# module dependencies
+LIBS += -L$$DESTDIR \
+    -lorm
+INCLUDEPATH += ../orm ../app
+DEPENDPATH += . \
+    ../orm
+TARGETDEPS += $$DESTDIR/liborm.a
+maemo { 
+    LIBS += -L$$DESTDIR \
+        -lqalarm \
+        -lalarm
+    INCLUDEPATH += ../alarm
+    DEPENDPATH += ../alarm
+    TARGETDEPS += $$DESTDIR/libqalarm.a
+}
+HEADERS += event.h \
+    conference.h \
+    track.h \
+    delegate.h \
+    eventmodel.h \
+    treeview.h \
+    room.h 
+SOURCES += event.cpp \
+    conference.cpp \
+    track.cpp \
+    delegate.cpp \
+    eventmodel.cpp \
+    treeview.cpp \
+    room.cpp 
diff --git a/src/mvc/room.cpp b/src/mvc/room.cpp
new file mode 100644 (file)
index 0000000..57c7f10
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "room.h"
+
+QString const Room::sTableName = QString("room");
+int const Room::sTableColCount = 3;
+const QString Room::NAME = "name";
+
+QSqlRecord const Room::sColumns = Room::toRecord(QList<QSqlField>()
+    << QSqlField("id", QVariant::Int)
+    << QSqlField(NAME, QVariant::String)
+    << QSqlField("picture", QVariant::String));
+
+Room Room::retrieveByName(QString name)
+{
+    QSqlQuery query;
+    query.prepare(
+            selectQuery()
+            + QString("WHERE %1.name = :name").arg(sTableName));
+    query.bindValue(":name", name);
+    return loadOne(query);
+}
+
+QList<Room> Room::getAll()
+{
+    QSqlQuery query;
+    query.prepare(selectQuery());
+    return load(query);
+}
+
+Room Room::retrieve(int id)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery()
+            + QString("WHERE %1.id = :id").arg(sTableName));
+    query.bindValue(":id", id);
+    return loadOne(query);
+}
+
+QString Room::retrieveRoomName(int id)
+{
+    Room room = retrieve(id);
+    return room.name();
+}
+
diff --git a/src/mvc/room.h b/src/mvc/room.h
new file mode 100644 (file)
index 0000000..dd78e58
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ROOM_H_
+#define ROOM_H_
+
+#include <ormrecord.h>
+
+class Room : public OrmRecord<Room>
+{
+public:
+    static const QSqlRecord sColumns;
+    static QString const sTableName;
+    static const int sTableColCount;
+    static const QString NAME;
+public:
+    int id() const { return value("id").toInt(); }
+    void setId(int id) { setValue("id", id); }
+    QString name() const { return value("name").toString(); }
+    void setName(const QString & type) { setValue("name", type); }
+    int insert();
+public:
+    static QList<Room> getAll();
+    static Room retrieve(int id);
+    static QString retrieveRoomName(int id);
+    static Room retrieveByName(QString name);
+};
+
+#endif /* ROOM_H_ */
diff --git a/src/mvc/track.cpp b/src/mvc/track.cpp
new file mode 100644 (file)
index 0000000..447eec3
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "track.h"
+
+QString const Track::sTableName = QString("track");
+int const Track::sTableColCount = 2;
+const QString Track::NAME = "name";
+
+QSqlRecord const Track::sColumns = Track::toRecord(QList<QSqlField>()
+    << QSqlField("id", QVariant::Int)
+    << QSqlField(NAME, QVariant::String));
+
+class TrackInsertException : OrmSqlException
+{
+public:
+    TrackInsertException(const QString& text) : OrmSqlException(text) {}
+};
+
+int Track::insert()
+{
+    QSqlQuery query;
+    query.prepare("INSERT INTO " + sTableName + " (" + NAME + ")" + " VALUES " + "(\"" + name() + "\")");
+    if (!query.exec())
+    {
+        throw TrackInsertException("Exec Error");
+    }
+    QVariant variant = query.lastInsertId();
+    if (variant.isValid())
+        return variant.toInt();
+    else
+        throw TrackInsertException("Last Insert Id Error");
+}
+
+Track Track::retrieveByName(QString name)
+{
+    QSqlQuery query;
+    query.prepare(
+            selectQuery()
+            + QString("WHERE %1.name = :name").arg(sTableName));
+    query.bindValue(":name", name);
+    return loadOne(query);
+}
+
+QList<Track> Track::getAll()
+{
+    QSqlQuery query;
+    query.prepare(selectQuery());
+    return load(query);
+}
+
+Track Track::retrieve(int id)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery()
+            + QString("WHERE %1.id = :id").arg(sTableName));
+    query.bindValue(":id", id);
+    return loadOne(query);
+}
+
+QString Track::retrieveTrackName(int id)
+{
+    Track track = retrieve(id);
+    return track.name();
+}
diff --git a/src/mvc/track.h b/src/mvc/track.h
new file mode 100644 (file)
index 0000000..39960d1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRACK_H_
+#define TRACK_H_
+
+#include <ormrecord.h>
+
+class Track : public OrmRecord<Track>
+{
+public:
+    static const QSqlRecord sColumns;
+    static QString const sTableName;
+    static const int sTableColCount;
+    static const QString NAME;
+public:
+    int id() const { return value("id").toInt(); }
+    void setId(int id) { setValue("id", id); }
+    QString name() const { return value("name").toString(); }
+    void setName(const QString & type) { setValue("name", type); }
+    int insert();
+public:
+    static QList<Track> getAll();
+    static Track retrieve(int id);
+    static QString retrieveTrackName(int id);
+    static Track retrieveByName(QString name);
+};
+
+#endif /* TRACK_H_ */
diff --git a/src/mvc/treeview.cpp b/src/mvc/treeview.cpp
new file mode 100644 (file)
index 0000000..ee6419f
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QMouseEvent>
+
+#include "treeview.h"
+#include "delegate.h"
+#include "event.h"
+#include "conference.h"
+#include "eventmodel.h"
+
+#ifdef MAEMO
+#include <alarm.h>
+#endif
+
+#include <QDebug>
+
+TreeView::TreeView(QWidget *aParent)
+    : QTreeView(aParent)
+{
+    connect(this, SIGNAL(clicked(QModelIndex)), SLOT(handleItemClicked(QModelIndex)));
+}
+
+void TreeView::mouseReleaseEvent(QMouseEvent *aEvent)
+{
+    QModelIndex index = currentIndex();
+    QPoint point = aEvent->pos();
+
+    // test whether we have handled the mouse event
+    if(!testForControlClicked(index,point))
+    {
+        // pass the event to the Base class, so item clicks/events are handled correctly
+        QTreeView::mouseReleaseEvent(aEvent);
+    }
+}
+
+// returns bool if some Control was clicked
+bool TreeView::testForControlClicked(const QModelIndex &aIndex, const QPoint &aPoint)
+{
+    bool handled = false;
+
+    if(!aIndex.isValid())
+        return handled;
+
+    int confId = Conference::activeConference();
+    QRect rect = visualRect(aIndex); // visual QRect of selected/clicked item in the list
+    Delegate *delegate = static_cast<Delegate*>(itemDelegate(aIndex));
+    switch(delegate->whichControlClicked(aIndex,aPoint))
+    {
+        case Delegate::FavouriteControlOn:
+        case Delegate::FavouriteControlOff:
+            {
+                // handle Favourite Control clicked
+                Event event = Event::getById(aIndex.data().toInt(),confId);
+
+                QList<Event> conflicts = Event::conflictEvents(event.id(),Conference::activeConference());
+                if(event.isFavourite())
+                    event.setFavourite(false);
+                else
+                    event.setFavourite(true);
+                event.update("favourite");
+
+                qDebug() << " FAVOURITE [" << qVariantValue<QString>(aIndex.data()) << "] -> " << event.isFavourite();
+
+                if(event.isFavourite())
+                {
+                    // event has became 'favourite' and so 'conflicts' list may have changed
+                    conflicts = Event::conflictEvents(event.id(),Conference::activeConference());
+                }
+
+                // have to emit 'eventHasChanged' signal on all events in conflict
+                for(int i=0; i<conflicts.count(); i++)
+                    emit(eventHasChanged(conflicts[i].id()));
+
+                // since the Favourite icon has changed, update TreeViews accordingly
+                // all TreeViews have to listen on this signal
+                emit(eventHasChanged(event.id(),true));
+
+                handled = true;
+            }
+            break;
+        case Delegate::AlarmControlOn:
+        case Delegate::AlarmControlOff:
+            {
+                // handle Alarm Control clicked
+                Event event = Event::getById(aIndex.data().toInt(),confId);
+                if(event.hasAlarm())
+                {
+                    event.setHasAlarm(false); // update DB
+#ifdef MAEMO
+                    // remove alarm from the 'alarmd' alrms list
+                    Alarm alarm;
+                    alarm.deleteAlarm(event.id());
+                    // TODO: test if removing was successfull
+#endif /* MAEMO */
+                }
+                else
+                {
+                    event.setHasAlarm(true);
+#ifdef MAEMO
+                    // add alarm to the 'alarmd'
+                    Alarm alarm;
+                    //int cookie = alarm.addAlarm(event.id(),QDateTime::currentDateTime().addSecs(10)); // testing
+                    int cookie = alarm.addAlarm(event.id(),event.start().addSecs(-15*60)); // 15 minutes before real start
+                    qDebug() << "cookie: " << cookie;
+#endif /* MAEMO */
+                }
+                event.update("alarm");
+                qDebug() << " ALARM [" << qVariantValue<QString>(aIndex.data()) << "] -> " << event.hasAlarm();
+                // since the Alarm icon has changed, update TreeView accordingly
+                // all TreeViews have to listen on this signal
+                emit(eventHasChanged(event.id()));
+                handled = true;
+            }
+            break;
+        case Delegate::MapControl:
+            {
+                // handle Alarm Control clicked
+                qDebug() << "MAP CLICKED: " << qVariantValue<QString>(aIndex.data());
+                emit(requestForMap(aIndex));
+                handled = true;
+            }
+        break;
+        case Delegate::WarningControl:
+        {
+
+            qDebug() << "WARNING CLICKED: " << qVariantValue<QString>(aIndex.data());
+            emit(requestForConflicts(aIndex));
+            handled = true;
+        }
+        break;
+        case Delegate::ControlNone:
+        default:
+            {
+                // item was clicked, but not a control
+                handled = false;
+            }
+    };
+
+    return handled;
+}
+
+void TreeView::handleItemClicked(const QModelIndex &index)
+{
+    if(!index.parent().isValid()) // time-group
+    {
+        if(isExpanded(index))
+            setExpanded(index, false);
+        else
+            setExpanded(index, true);
+    }
+}
+
+void TreeView::setAllExpanded(bool aExpanded)
+{
+    for(int i=0; i<model()->rowCount(QModelIndex()); i++)
+    {
+        setExpanded(model()->index(i,0,QModelIndex()),aExpanded);
+    }
+}
+
diff --git a/src/mvc/treeview.h b/src/mvc/treeview.h
new file mode 100644 (file)
index 0000000..2c7a0fb
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TREEVIEW_H
+#define TREEVIEW_H
+
+#include <QTreeView>
+
+class TreeView : public QTreeView
+{
+    Q_OBJECT
+public:
+    TreeView(QWidget *aParent = NULL);
+    ~TreeView() {}
+private:
+    void mouseReleaseEvent(QMouseEvent *aEvent);
+    bool testForControlClicked(const QModelIndex &aIndex, const QPoint &aPoint);
+public slots:
+    void setAllExpanded(bool aExpanded); // (aExpanded==true) => expanded; (aExpanded==false) => collapsed
+private slots:
+    void handleItemClicked(const QModelIndex &index);
+signals:
+    void requestForMap(const QModelIndex &aIndex);
+    void requestForConflicts(const QModelIndex &aIndex);
+    void eventHasChanged(int aEventId, bool aReloadModel = false); // emited when user changes some event details, eg. sets it Favourite
+};
+
+#endif /* TREEVIEW_H */
+
diff --git a/src/orm/orm.pro b/src/orm/orm.pro
new file mode 100644 (file)
index 0000000..91472fe
--- /dev/null
@@ -0,0 +1,9 @@
+TEMPLATE = lib
+TARGET = orm
+DESTDIR = ../bin
+CONFIG += static
+QT += sql
+
+# module dependencies
+DEPENDPATH += .
+HEADERS += ormrecord.h
diff --git a/src/orm/ormrecord.h b/src/orm/ormrecord.h
new file mode 100644 (file)
index 0000000..dfafc94
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2010 Ixonos Plc.
+ *
+ * This file is part of fosdem-schedule.
+ *
+ * fosdem-schedule 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.
+ *
+ * fosdem-schedule 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
+ * fosdem-schedule.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef ORMRECORD_H
+#define ORMRECORD_H
+
+#include <QSqlQuery>
+#include <QSqlRecord>
+#include <QSqlField>
+#include <QSqlError>
+#include <QStringList>
+#include <QDateTime>
+#include <QDebug>
+
+class OrmException
+{
+public:
+    OrmException(const QString& text) : mText(text) {};
+    virtual ~OrmException(){};
+    virtual const QString& text() const { return mText; }
+private:
+    QString mText;
+};
+
+class OrmNoObjectException : public OrmException
+{
+public:
+    OrmNoObjectException() : OrmException("No object exception"){};
+    ~OrmNoObjectException(){};
+};
+
+class OrmSqlException : public OrmException
+{
+public:
+    OrmSqlException(const QString& text) : OrmException( QString("Sql error: ") + text ) {};
+    ~OrmSqlException(){};
+};
+
+template <typename T>
+class OrmRecord : protected QSqlRecord
+{
+public:
+    OrmRecord();
+    static T hydrate(const QSqlRecord& record);
+    void update(QString col, QVariant value = QVariant()); // updates specified column 'col'
+
+protected:
+    QVariant value(QString col) const;
+    void setValue(QString col, QVariant value);
+
+    static T loadOne(QSqlQuery query);
+    static QList<T> load(QSqlQuery query);
+
+    // auxiliary methods
+    static QSqlRecord toRecord(const QList<QSqlField> & columnList);
+    // all record items/columns are in one table
+    static QString columnsForSelect(const QString& prefix = QString());
+    static QString selectQuery();
+    static QString updateQuery();
+
+    static QVariant convertToC(QVariant value, QVariant::Type colType);
+    static QVariant convertToDb(QVariant value, QVariant::Type colType);
+};
+
+template <typename T>
+OrmRecord<T>::OrmRecord()
+{
+    QSqlRecord::operator=(T::sColumns);
+}
+
+template <typename T>
+T OrmRecord<T>::hydrate(const QSqlRecord& record)
+{
+    T object;
+    object.QSqlRecord::operator=(record);
+    return object;
+}
+
+// updates specified column 'col'
+// if the value is not specified  as an argument,
+// it's taken from the reford itself
+// see also: setValue() method for more details
+template <typename T>
+void OrmRecord<T>::update(QString col, QVariant value)
+{
+    QSqlQuery query;
+    query.prepare(QString(updateQuery() + "SET %1 = :col WHERE id = :id").arg(col));
+    if(value.isValid()) // take 'col' value from the method's arguments
+        query.bindValue(":col", value);
+    else // take 'col' value from the record; see setValue()
+        query.bindValue(":col", convertToDb(this->value(col), this->value(col).type()));
+    query.bindValue(":id", this->value("id"));
+    //query.bindValue(":id", convertToDb(value("id"), QVariant::Int));
+    query.exec();
+}
+
+template <typename T>
+QVariant OrmRecord<T>::value(QString col) const
+{
+    return convertToC(QSqlRecord::value(col), T::sColumns.field(col).type());
+}
+
+template <typename T>
+void OrmRecord<T>::setValue(QString col, QVariant value)
+{
+    QSqlRecord::setValue(col, convertToDb(value, T::sColumns.field(col).type()));
+}
+
+template <typename T>
+T OrmRecord<T>::loadOne(QSqlQuery query)
+{
+    if (!query.isActive())
+    {
+        if (!query.exec())
+        {
+            throw OrmSqlException(query.lastError().text());
+        }
+    }
+
+    if (!query.next())
+    {
+        throw OrmNoObjectException();
+    }
+
+    return hydrate(query.record());
+}
+
+template <typename T>
+QList<T> OrmRecord<T>::load(QSqlQuery query)
+{
+    if (!query.isActive())
+    {
+        if (!query.exec())
+        {
+            qDebug() << "Error: " << query.lastError().driverText() << "; Type: " << query.lastError().type();
+            throw OrmSqlException(query.lastError().text());
+        }
+        else
+        {
+            /*qDebug() << "SQL OK";*/
+        }
+    }
+
+    QList<T> objects;
+    while (query.next())
+    {
+        objects << hydrate(query.record());
+    }
+    /*qDebug() << "Fetch done";*/
+    return objects;
+}
+
+template <typename T>
+QString OrmRecord<T>::columnsForSelect(const QString& prefix)
+{
+    QStringList prefixedColumns;
+    for (int i=0; i<T::sColumns.count(); i++)
+    {
+        prefixedColumns.append(prefix.isEmpty() ?
+            T::sColumns.field(i).name() :
+            QString("%1.%2").arg(prefix, T::sColumns.field(i).name()));
+    }
+    return prefixedColumns.join(",");
+}
+
+template <typename T>
+QString OrmRecord<T>::selectQuery()
+{
+    return QString("SELECT %1 FROM %2 ").arg(columnsForSelect(), T::sTableName);
+}
+
+template <typename T>
+QString OrmRecord<T>::updateQuery()
+{
+    return QString("UPDATE %1 ").arg(T::sTableName);
+}
+
+template <typename T>
+QSqlRecord OrmRecord<T>::toRecord(const QList<QSqlField> & columnList)
+{
+    QSqlRecord record;
+    for(int i=0; i< columnList.count(); i++)
+    {
+        record.append(columnList[i]);
+    }
+    return record;
+}
+
+template <typename T>
+QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
+{
+    if (colType == QVariant::DateTime && value.canConvert<uint>())
+    {
+        QDateTime date;
+        date.setTimeSpec(Qt::UTC);
+        date.setTime_t(value.toUInt());
+        return date;
+    }
+
+    return value;
+}
+
+template <typename T>
+QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
+{
+    if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
+    {
+        return value.toDateTime().toTime_t();
+    }
+
+    return value;
+}
+
+#endif // ORMRECORD_H
+
diff --git a/src/schedule.en.xml b/src/schedule.en.xml
new file mode 100755 (executable)
index 0000000..7a0549f
--- /dev/null
@@ -0,0 +1,6304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schedule>
+ <conference>
+  <title>FOSDEM 2010</title>
+  <subtitle>Free and Opensource Software Developers European Meeting</subtitle>
+  <venue>ULB (Campus Solbosch)</venue>
+  <city>Brussels</city>
+  <start>2010-02-06</start>
+  <end>2010-02-07</end>
+  <days>2</days>
+  <day_change>08:00</day_change>
+  <timeslot_duration>00:15</timeslot_duration>
+ </conference>
+ <day date="2010-02-06" index="1">
+  <room name="Janson">
+   <event id="819">
+    <start>10:00</start>
+    <duration>00:45</duration>
+    <room>Janson</room>
+    <tag>welcome</tag>
+    <title>Welcome</title>
+    <subtitle></subtitle>
+    <track>Keynotes</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>FOSDEM Opening Talk</abstract>
+    <description>FOSDEM was started under the name OSDEM (Open Source Developers of Europe Meeting) by Raphael Bauduin. Raphael says that, since he felt he lacked the brains to properly contribute to the open source community, he wanted to contribute by launching a European event in Brussels. It was an immediate success, with speakers coming from all over.\r
+\r
+The FOSDEM conference is coming to its tenth birthday. We will quickly go over the history and present.</description>
+    <persons>
+     <person id="46">FOSDEM Staff</person>
+    </persons>
+    <links>
+    </links>
+   </event>
+   <event id="803">
+    <start>10:45</start>
+    <duration>00:45</duration>
+    <room>Janson</room>
+    <tag>promoting</tag>
+    <title>Promoting Open Source Methods at a Large Company</title>
+    <subtitle></subtitle>
+    <track>Keynotes</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>This talk will\r
+cover Aerosource, our project to bring open source development tools\r
+and methods to internal developers.</abstract>
+    <description>At the Aerospace corporation our approximately 2500 engineers developer\r
+a lot of software in the course of doing their jobs.  This talk will\r
+cover Aerosource, our project to bring open source development tools\r
+and methods to internal developers.  Aerosource is a project hosting\r
+environment built on open source tools including Apache, FreeBSD,\r
+PostgreSQL, Python, and Trac.  We will share our experiences and\r
+successes at promoting open source methods in a traditionally closed\r
+environment.</description>
+    <persons>
+     <person id="665">Brooks Davis</person>
+    </persons>
+    <links>
+    </links>
+   </event>
+   <event id="802">
+    <start>11:45</start>
+    <duration>00:45</duration>
+    <room>Janson</room>
+    <tag>eviloninternet</tag>
+    <title>Evil on the Internet</title>
+    <subtitle></subtitle>
+    <track>Keynotes</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>This talk will show\r
+you live examples of these sites, explain how they work, and tell you\r
+what we currently know about the criminals who operate them.</abstract>
+    <description>There's a lot of evil things on the Internet if you know where to look\r
+for them. Phishing websites collect banking credentials; mule\r
+recruitment websites entice people into money laundering; fake escrow\r
+sites defraud the winners of online auctions; fake banks hold the cash\r
+for fake African dictators; and there are even Ponzi scheme websites\r
+where (almost) everyone knows that they're a scam.  This talk will show\r
+you live examples of these sites, explain how they work, and tell you\r
+what we currently know about the criminals who operate them.</description>
+    <persons>
+     <person id="664">Richard Clayton</person>
+    </persons>
+    <links>
+    </links>
+   </event>
+   <event id="809">
+    <start>14:00</start>
+    <duration>00:45</duration>
+    <room>Janson</room>
+    <tag>systemtap</tag>
+    <title>What is my system doing - Full System Observability with SystemTap</title>
+    <subtitle></subtitle>
+    <track>Monitoring</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>SystemTap an application that observes your system on multiple levels, from kernel, libraries, applications, java to database transactions. SystemTap is a new player in the monitoring world!:t</abstract>
+    <description>Ever wondered what your system is really doing? Even if your whole system consists of Free Software you might still be scratching your head about what is really going on. Reading all the sources or staring at a core dump after the fact only gets you that far. You have to observe your system while it is running. Luckily the last few years there has been lots of improvements in GNU/Linux around how to monitor, trace, profile and debug your system. Kernel ftrace, pref, tracepoints, better debuginfo, application and library probe points, tapsets and compatibility with dtrace. Systemtap can take advantage of it all and provides a powerful way to get full system observability.\r
+\r
+Want to dive deep into applications, java processes or the linux kernel without needing to stop or interrupt anything? SystemTap is the tool of choice for complex tasks that may require live analysis, programmable on-line response, and whole-system symbolic access. SystemTap can also handle simple tracing jobs. Learn how to setup SystemTap, what ready to run scripts there are, and how to tailor your probes to specific applications or kernel usage patterns.\r
+\r
+SystemTap can observe on multiple levels, from kernel, libraries, applications, java to database transactions. To help users to get a better view what an application is doing you can add tapsets and static markers. And such markers can be made compatible with dtrace (to make your solaris hacker friends happy). There are already lots of packages that provide such high level observability, Postgresql, Java hotspot, Xorg, Python, Firefox, etc. Learn how to rapid prototype observability of your application through tapsets with function and statement probes (on any existing binary) and how to add high-level (zero-overhead) markers to your package sources that tell users about everything important, passes, transactions, service starting/stopping, etc.</description>
+    <persons>
+     <person id="194">Mark Wielaard</person>
+    </persons>
+    <links>
+     <link href="http://sourceware.org/systemtap/">Homepage</link>
+    </links>
+   </event>
+   <event id="810">
+    <start>15:00</start>
+    <duration>00:45</duration>
+    <room>Janson</room>
+    <tag>ganglia</tag>
+    <title>Ganglia: 10 years of monitoring clusters and grids</title>
+    <subtitle></subtitle>
+    <track>Monitoring</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>During the talk Bernard will give an overview of Ganglia's strong points and it's technical architecture.</abstract>
+    <description>This talk will start off with a brief overview of the early beginnings of the project and how it has become the de facto standard for monitoring clusters and grids. The talk will then dive into the technical architecture of the system, discuss scalability issues, challenges ahead in adapting the software for cloud environments and other future developments. If you work with a lot of computers, then this talk is for you.\r
+\r
+Ganglia is a scalable system performance monitoring software started by Matt Massie in 1999 while he was at the University of California, Berkeley working on the Millennium Project.  Since the inception of the project, it has seen 40+ releases and 299,208 total downloads recorded by SourceForge.net. Ganglia is simple to install and use and is available on most UNIX platforms. 30+ system metrics such as CPU load, memory usage, network traffic are collected by default and can be further extended via a command line metric reporting tool or pluggable modules written in C or Python. Ganglia is being used extensively all over the world by organizations large and small.</description>
+    <persons>
+     <person id="670">Bernard Li</person>
+    </persons>
+    <links>
+    </links>
+   </event>
+   <event id="808">
+    <start>16:00</start>
+    <duration>00:45</duration>
+    <room>Janson</room>
+    <tag>flapjack</tag>
+    <title>Starting the sysadmin tools renaissance: Flapjack + cucumber-nagios</title>
+    <subtitle></subtitle>
+    <track>Monitoring</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>Monitoring software is ripe for a renaissance. Now is the time to for building new tools and rethinking our problems. \r
+Leading the charge are two projects: cucumber-nagios, and Flapjack.</abstract>
+    <description>A systems administrator's role in today's technology landscape has never been so important. It's our responsibility to manage provisioning and maintenance of massive infrastructures, to anticipate ahead of time when capacity must be grown or shrunk, and increasingly, to make sure our applications scale. \r
+\r
+While developer tools have improved tremendously, we sysadmins are still living in the dark ages, other than a few shining beacons of hope such as Puppet. We're still trying to make Nagios scale. We're still writing the same old monitoring checks. Getting statistics out of our applications is tedious and difficult, but increasingly important to scaling. \r
+\r
+cucumber-nagios lets you describe how a website should work in natural language, and outputs whether it does in the Nagios plugin format. It includes a standard library of website interactions, so you don't have to rewrite the same Nagios checks over and over. \r
+\r
+cucumber-nagios can also be used to check SSH logins, filesystem interactions, mail delivery, and Asterisk dialplans. By lowering the barrier of entry to writing fully featured checks, there's no reason not to start testing all of your infrastructure. But as you start adding more checks to your monitoring system you're going to notice slowdowns and reliability problems - enter Flapjack\r
+\r
+Flapjack is a scalable and distributed monitoring system. It natively talks the Nagios plugin format (so you can use all your existing Nagios checks), and can easily be scaled from 1 server to 1000. \r
+\r
+Flapjack breaks the monitoring lifecycle into several distinct chunks: workers that execute checks, notifiers that notify when checks fail, and an admin interface to manage checks and events. \r
+\r
+By breaking the monitoring lifecycle up, it becomes incredibly easy to scale your monitoring system with your infrastructure. Need to monitor more servers? Just add another server to the pool of workers. Need to take down your workers for maintenance? Just spin up another pool, and turn off the old one.</description>
+    <persons>
+     <person id="668">Lindsay Holmwood</person>
+    </persons>
+    <links>
+     <link href="http://flapjack-project.com/">Flapjack</link>
+     <link href="http://auxesis.github.com/cucumber-nagios">cucumber-nagios</link>
+    </links>
+   </event>
+  </room>
+  <room name="Chavanne">
+   <event id="799">
+    <start>14:00</start>
+    <duration>00:45</duration>
+    <room>Chavanne</room>
+    <tag>maemo</tag>
+    <title>Maemo 6 security framework, making happy DRM business and freedom lovers with the same device</title>
+    <subtitle></subtitle>
+    <track>Security</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>The presentation will cover the Maemo Platform Security Architecture in more details, providing a deeper technical view on its components and their interaction.</abstract>
+    <description>The purpose of the Platform Security in the Maemo 6 platform is to protect the owner of a Maemo-powered device from getting her personal, private data and passwords from being stolen and used for malicious purposes, to prevent a malware from misusing a device and incurring costs on user, to prevent a user from accidentally breaking the device and to make the platform meet the requirements set by such third party software that requires a safe execution environment.\r
+\r
+The presentation will cover the Maemo Platform Security Architecture in more details, providing a deeper technical view on its components and their interaction.</description>
+    <persons>
+     <person id="661">Elena Reshetova</person>
+    </persons>
+    <links>
+    </links>
+   </event>
+   <event id="797">
+    <start>15:00</start>
+    <duration>00:45</duration>
+    <room>Chavanne</room>
+    <tag>nmap</tag>
+    <title>The Nmap scripting engine</title>
+    <subtitle></subtitle>
+    <track>Security</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>The Nmap Scripting Engine extends the results of an Nmap port scan. It\r
+combines the Lua programming language, a library of network functions,\r
+and the results provided by other parts of Nmap to give more information\r
+about network hosts and their open ports.</abstract>
+    <description>There are standard scripts that grab SSH host keys or SSL certificates, discover the remote date\r
+and time, check for weak passwords and unpatched vulnerabilites, and\r
+much more.\r
+\r
+The talk will explain how the scripting engine fits in with Nmap's other\r
+functions, the structure of a script, and how to modify a script or\r
+write your own. We'll see how the scripting engine can benefit casual\r
+users, researchers, and security auditors. Finally there will be a brief\r
+overview of what's new in Nmap and its associated tools for the benefit\r
+of casual users.</description>
+    <persons>
+     <person id="658">David Fifield</person>
+    </persons>
+    <links>
+     <link href="http://nmap.org">Official Website</link>
+     <link href="http://nmap.org/book/nse.html">NSF Chapters from the Nmap book</link>
+    </links>
+   </event>
+   <event id="800">
+    <start>16:00</start>
+    <duration>00:45</duration>
+    <room>Chavanne</room>
+    <tag>ossec</tag>
+    <title>OSSEC</title>
+    <subtitle></subtitle>
+    <track>Security</track>
+    <type>Podium</type>
+    <language>English</language>
+    <abstract>Expect an overview of the basic architecture as well as practical examples of how to customize OSSEC to manage logging from your infrastructure and applications.</abstract>
+    <description>Log management, Intrusion detection/prevention and event correlation is a challenge we have been facing for decades.  Most of us have been able to ignore it but with developments in regulatory compliance (PCI-DSS, HIPAA, SOX, ISO27K, ...) companies are required to investigate solutions.  \r
+In this talk we will firstly touch upon the\r
+problems that will be faced during such a project and how log management will look in the future (new standards are on their way).   After this boring introduction to\r
+the magical world that is log management and intrusion detection we will delve into the solution that is presented with OSSEC.  While labeled as a Host-based Intrusion\r
+Detection System (HIDS), OSSEC provides you with a complete arsenal of functionalities that allow you to build a log management solution which will translate\r
+the most cryptic log message into a clear and actionable alert.  Expect an overview of the basic architecture as well as practical examples of how to customize OSSEC to manage logging from your infrastructure and applications.</description>
+    <persons>
+     <person id="662">Wim Remes</person>
+    </persons>
+    <links>
+    </links>
+   </event>
+  </room>
+  <room name="Ferrer">
+   <event id="832">
+    <start>13:00</start>
+    <duration>00:15</duration>
+    <room>Ferrer</room>
+    <tag>fosdem</tag>
+    <title>FOSDEM: Lightning Opening Talk</title>
+    <subtitle></subtitle>
+    <track>Lightning Talks</track>
+    <type>Lightning-Talk</type>
+    <language>English</language>
+    <abstract>The main goal is to buffer the time between the opening of the room, and the first real lightning talk.\r
+\r
+If time permits, there will be a lightning talk about the lightning talks: with statistics about the proposals and acceptances, and the story of how these lightning talks are organized. Extra time can be filled with questions related to the organisation of the FOSDEM conference at large.</abstract>
+    <description>The FOSDEM Lightning Talks are organized by Mattias 'Tias' Guns since 2007. The lightning talks allow projects that do not fit in a developer room to present themselves to the large developer audience at FOSDEM.\r
+\r
+Lightning Talks can be described as the 15 minutes of fame for all free or open source projects. During exactly 15 minutes, one person gets to present the project or any aspect of it. All the lightning talks happen in a large room that can host up to 300 people.</description>
+    <persons>
+     <person id="19">Tias Guns</person>
+    </persons>
+    <links>
+     <link href="http://fosdem.org">http://fosdem.org</link>
+    </links>
+   </event>
+   <event id="833">
+    <start>13:15</start>
+    <duration>00:15</duration>
+    <room>Ferrer</room>
+    <tag>limux</tag>
+    <title>LiMux: 5 years on the way to free software in Munich</title>
+    <subtitle></subtitle>
+    <track>Lightning Talks</track>
+    <type>Lightning-Talk</type>
+    <language>English</language>
+   &nbs