Merge lp:~meths/openlp/testing into lp:openlp

Proposed by Jon Tibble
Status: Merged
Merged at revision: not available
Proposed branch: lp:~meths/openlp/testing
Merge into: lp:openlp
Diff against target: None lines
To merge this branch: bzr merge lp:~meths/openlp/testing
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Raoul Snyman Approve
Review via email: mp+11667@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jon Tibble (meths) wrote :

dos2unix

Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
Revision history for this message
Tim Bentley (trb143) wrote :

Approved

review: Approve
lp:~meths/openlp/testing updated
536. By Jon Tibble

For Jon

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'demo_theme.xml'
--- demo_theme.xml 2008-10-07 19:12:32 +0000
+++ demo_theme.xml 2009-09-13 15:14:45 +0000
@@ -1,17 +1,17 @@
1<?xml version="1.0" encoding="iso-8859-1"?>1<?xml version="1.0" encoding="iso-8859-1"?>
2<Theme>2<Theme>
3 <Name>openlp.org 2.0 Demo Theme</Name>3 <Name>openlp.org 2.0 Demo Theme</Name>
4 <BackgroundType>2</BackgroundType>4 <BackgroundType>2</BackgroundType>
5 <BackgroundParameter1>./openlp/core/test/data_for_tests/treesbig.jpg</BackgroundParameter1>5 <BackgroundParameter1>./openlp/core/test/data_for_tests/treesbig.jpg</BackgroundParameter1>
6 <BackgroundParameter2>clBlack</BackgroundParameter2>6 <BackgroundParameter2>clBlack</BackgroundParameter2>
7 <BackgroundParameter3/>7 <BackgroundParameter3/>
8 <FontName>Tahoma</FontName>8 <FontName>Tahoma</FontName>
9 <FontColor>clWhite</FontColor>9 <FontColor>clWhite</FontColor>
10 <FontProportion>16</FontProportion>10 <FontProportion>16</FontProportion>
11 <Shadow>-1</Shadow>11 <Shadow>-1</Shadow>
12 <ShadowColor>$00000001</ShadowColor>12 <ShadowColor>$00000001</ShadowColor>
13 <Outline>-1</Outline>13 <Outline>-1</Outline>
14 <OutlineColor>clRed</OutlineColor>14 <OutlineColor>clRed</OutlineColor>
15 <HorizontalAlign>2</HorizontalAlign>15 <HorizontalAlign>2</HorizontalAlign>
16 <VerticalAlign>2</VerticalAlign>16 <VerticalAlign>2</VerticalAlign>
17</Theme>17</Theme>
1818
=== modified file 'documentation/pyqt-sql-py2exe.txt'
--- documentation/pyqt-sql-py2exe.txt 2008-11-27 20:14:38 +0000
+++ documentation/pyqt-sql-py2exe.txt 2009-09-13 15:14:45 +0000
@@ -1,58 +1,58 @@
1This content can be found at this URL:1This content can be found at this URL:
2http://netsuperbrain.com/Postmodern%20PostgreSQL%20Application%20Development.pdf2http://netsuperbrain.com/Postmodern%20PostgreSQL%20Application%20Development.pdf
33
4Page 11-15: QtDesigner4Page 11-15: QtDesigner
5Page 18-20: SQLAlchemy5Page 18-20: SQLAlchemy
6Page 21-23: PyQt - widget6Page 21-23: PyQt - widget
7Page 24 : main7Page 24 : main
8Page 28 : py2exe and release8Page 28 : py2exe and release
99
1010
11==============================11==============================
12This is the destilled content.12This is the destilled content.
13==============================13==============================
1414
15----------------15----------------
16** sqlalchemy **16** sqlalchemy **
17----------------17----------------
18from sqlalchemy import create_engine, MetaData, Table18from sqlalchemy import create_engine, MetaData, Table
19from sqlalchemy.orm import sessionmaker, mapper19from sqlalchemy.orm import sessionmaker, mapper
20engine = create_engine( 'postgres://postgres@localhost/customers' )20engine = create_engine( 'postgres://postgres@localhost/customers' )
21metadata = MetaData( bind=engine, reflect=True)21metadata = MetaData( bind=engine, reflect=True)
22Session = sessionmaker(bind=engine, autoflush=True,22Session = sessionmaker(bind=engine, autoflush=True,
23 transactional=True)23 transactional=True)
2424
25class Customer(object): pass25class Customer(object): pass
26mapper( Customer, Table('customers', metadata ) )26mapper( Customer, Table('customers', metadata ) )
2727
28session = Session()28session = Session()
29customer = Customer( businessName=“Jamb Safety”,29customer = Customer( businessName=“Jamb Safety”,
30 website=“www.jamb.com” )30 website=“www.jamb.com” )
31session.save( customer )31session.save( customer )
32for customer in Session.query(Customer).filter(32for customer in Session.query(Customer).filter(
33 Customer.businessName.like(“Jamb%”)):33 Customer.businessName.like(“Jamb%”)):
34 print customer.businessName34 print customer.businessName
35session.commit()35session.commit()
3636
37------------------------37------------------------
38** release and py2exe **38** release and py2exe **
39------------------------39------------------------
4040
41from distutils.core import setup41from distutils.core import setup
42import py2exe42import py2exe
43import glob43import glob
44setup(44setup(
45 name="Customers",45 name="Customers",
46 author="Sankel Software",46 author="Sankel Software",
47 author_email="david@sankelsoftware.com",47 author_email="david@sankelsoftware.com",
48 url="http://sankelsoftware.com",48 url="http://sankelsoftware.com",
49 license=“GPL",49 license=“GPL",
50 version=“1.0.0",50 version=“1.0.0",
51 windows=[ { "script":"main.py“,}],51 windows=[ { "script":"main.py“,}],
52 options={"py2exe":{"includes":["sip”]}},52 options={"py2exe":{"includes":["sip”]}},
53 data_files=[53 data_files=[
54 ("forms",glob.glob("forms/*.ui")),54 ("forms",glob.glob("forms/*.ui")),
55 ] )55 ] )
5656
57release:57release:
58python setup.py py2exe --quiet --dist-dir=dist58python setup.py py2exe --quiet --dist-dir=dist
5959
=== modified file 'openlp/core/test/data_for_tests/render_theme.xml'
--- openlp/core/test/data_for_tests/render_theme.xml 2009-03-12 20:19:24 +0000
+++ openlp/core/test/data_for_tests/render_theme.xml 2009-09-13 15:14:45 +0000
@@ -1,19 +1,19 @@
1<?xml version="1.0" encoding="iso-8859-1"?>1<?xml version="1.0" encoding="iso-8859-1"?>
2<Theme>2<Theme>
3 <Name>openlp.org Packaged Theme</Name>3 <Name>openlp.org Packaged Theme</Name>
4 <BackgroundType>0</BackgroundType>4 <BackgroundType>0</BackgroundType>
5 <BackgroundParameter1>clWhite</BackgroundParameter1>5 <BackgroundParameter1>clWhite</BackgroundParameter1>
6 <BackgroundParameter2/>6 <BackgroundParameter2/>
7 <BackgroundParameter3/>7 <BackgroundParameter3/>
8 <FontName>Tahoma</FontName>8 <FontName>Tahoma</FontName>
9 <FontColor>$00007F</FontColor>9 <FontColor>$00007F</FontColor>
10 <FontProportion>53</FontProportion>10 <FontProportion>53</FontProportion>
11 <FontUnits>pixels</FontUnits>11 <FontUnits>pixels</FontUnits>
12 <Shadow>0</Shadow>12 <Shadow>0</Shadow>
13 <ShadowColor>$000000</ShadowColor>13 <ShadowColor>$000000</ShadowColor>
14 <Outline>0</Outline>14 <Outline>0</Outline>
15 <OutlineColor>$000000</OutlineColor>15 <OutlineColor>$000000</OutlineColor>
16 <HorizontalAlign>0</HorizontalAlign>16 <HorizontalAlign>0</HorizontalAlign>
17 <VerticalAlign>0</VerticalAlign>17 <VerticalAlign>0</VerticalAlign>
18 <WrapStyle>1</WrapStyle>18 <WrapStyle>1</WrapStyle>
19</Theme>19</Theme>
2020
=== modified file 'openlp/core/theme/test/test_theme.xml'
--- openlp/core/theme/test/test_theme.xml 2009-03-12 20:19:24 +0000
+++ openlp/core/theme/test/test_theme.xml 2009-09-13 15:14:45 +0000
@@ -1,18 +1,18 @@
1<?xml version="1.0" encoding="iso-8859-1"?>1<?xml version="1.0" encoding="iso-8859-1"?>
2<Theme>2<Theme>
3 <Name>openlp.org Packaged Theme</Name>3 <Name>openlp.org Packaged Theme</Name>
4 <BackgroundType>2</BackgroundType>4 <BackgroundType>2</BackgroundType>
5 <BackgroundParameter1>sunset1.jpg</BackgroundParameter1>5 <BackgroundParameter1>sunset1.jpg</BackgroundParameter1>
6 <BackgroundParameter2/>6 <BackgroundParameter2/>
7 <BackgroundParameter3/>7 <BackgroundParameter3/>
8 <FontName>Tahoma</FontName>8 <FontName>Tahoma</FontName>
9 <FontColor>clWhite</FontColor>9 <FontColor>clWhite</FontColor>
10 <FontProportion>16</FontProportion>10 <FontProportion>16</FontProportion>
11 <FontUnits>pixels</FontUnits>11 <FontUnits>pixels</FontUnits>
12 <Shadow>-1</Shadow>12 <Shadow>-1</Shadow>
13 <ShadowColor>$00000001</ShadowColor>13 <ShadowColor>$00000001</ShadowColor>
14 <Outline>-1</Outline>14 <Outline>-1</Outline>
15 <OutlineColor>clRed</OutlineColor>15 <OutlineColor>clRed</OutlineColor>
16 <HorizontalAlign>2</HorizontalAlign>16 <HorizontalAlign>2</HorizontalAlign>
17 <VerticalAlign>0</VerticalAlign>17 <VerticalAlign>0</VerticalAlign>
18</Theme>18</Theme>
1919
=== modified file 'openlp/core/ui/amendthemeform.py'
--- openlp/core/ui/amendthemeform.py 2009-09-13 14:12:38 +0000
+++ openlp/core/ui/amendthemeform.py 2009-09-13 15:14:45 +0000
@@ -1,716 +1,716 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=42# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
33
4###############################################################################4###############################################################################
5# OpenLP - Open Source Lyrics Projection #5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2009 Raoul Snyman #7# Copyright (c) 2008-2009 Raoul Snyman #
8# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #8# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
9# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #9# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
10# --------------------------------------------------------------------------- #10# --------------------------------------------------------------------------- #
11# This program is free software; you can redistribute it and/or modify it #11# This program is free software; you can redistribute it and/or modify it #
12# under the terms of the GNU General Public License as published by the Free #12# under the terms of the GNU General Public License as published by the Free #
13# Software Foundation; version 2 of the License. #13# Software Foundation; version 2 of the License. #
14# #14# #
15# This program is distributed in the hope that it will be useful, but WITHOUT #15# This program is distributed in the hope that it will be useful, but WITHOUT #
16# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #16# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
17# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #17# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
18# more details. #18# more details. #
19# #19# #
20# You should have received a copy of the GNU General Public License along #20# You should have received a copy of the GNU General Public License along #
21# with this program; if not, write to the Free Software Foundation, Inc., 59 #21# with this program; if not, write to the Free Software Foundation, Inc., 59 #
22# Temple Place, Suite 330, Boston, MA 02111-1307 USA #22# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
23###############################################################################23###############################################################################
2424
25import logging25import logging
26import os, os.path26import os, os.path
2727
28from PyQt4 import QtCore, QtGui28from PyQt4 import QtCore, QtGui
29from openlp.core.lib import ThemeXML, Renderer, file_to_xml, str_to_bool, \29from openlp.core.lib import ThemeXML, Renderer, file_to_xml, str_to_bool, \
30 translate30 translate
3131
32from amendthemedialog import Ui_AmendThemeDialog32from amendthemedialog import Ui_AmendThemeDialog
3333
34log = logging.getLogger(u'AmendThemeForm')34log = logging.getLogger(u'AmendThemeForm')
3535
36class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):36class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
3737
38 def __init__(self, thememanager, parent=None):38 def __init__(self, thememanager, parent=None):
39 QtGui.QDialog.__init__(self, parent)39 QtGui.QDialog.__init__(self, parent)
40 self.thememanager = thememanager40 self.thememanager = thememanager
41 self.path = None41 self.path = None
42 self.theme = ThemeXML()42 self.theme = ThemeXML()
43 self.setupUi(self)43 self.setupUi(self)
44 #define signals44 #define signals
45 #Buttons45 #Buttons
46 QtCore.QObject.connect(self.Color1PushButton ,46 QtCore.QObject.connect(self.Color1PushButton ,
47 QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked)47 QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked)
48 QtCore.QObject.connect(self.Color2PushButton ,48 QtCore.QObject.connect(self.Color2PushButton ,
49 QtCore.SIGNAL(u'pressed()'), self.onColor2PushButtonClicked)49 QtCore.SIGNAL(u'pressed()'), self.onColor2PushButtonClicked)
50 QtCore.QObject.connect(self.FontMainColorPushButton,50 QtCore.QObject.connect(self.FontMainColorPushButton,
51 QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)51 QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)
52 QtCore.QObject.connect(self.FontFooterColorPushButton,52 QtCore.QObject.connect(self.FontFooterColorPushButton,
53 QtCore.SIGNAL(u'pressed()'),53 QtCore.SIGNAL(u'pressed()'),
54 self.onFontFooterColorPushButtonClicked)54 self.onFontFooterColorPushButtonClicked)
55 QtCore.QObject.connect(self.OutlineColorPushButton,55 QtCore.QObject.connect(self.OutlineColorPushButton,
56 QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)56 QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)
57 QtCore.QObject.connect(self.ShadowColorPushButton,57 QtCore.QObject.connect(self.ShadowColorPushButton,
58 QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked)58 QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked)
59 QtCore.QObject.connect(self.ImageToolButton,59 QtCore.QObject.connect(self.ImageToolButton,
60 QtCore.SIGNAL(u'pressed()'), self.onImageToolButtonClicked)60 QtCore.SIGNAL(u'pressed()'), self.onImageToolButtonClicked)
61 #Combo boxes61 #Combo boxes
62 QtCore.QObject.connect(self.BackgroundComboBox,62 QtCore.QObject.connect(self.BackgroundComboBox,
63 QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected)63 QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected)
64 QtCore.QObject.connect(self.BackgroundTypeComboBox,64 QtCore.QObject.connect(self.BackgroundTypeComboBox,
65 QtCore.SIGNAL(u'activated(int)'),65 QtCore.SIGNAL(u'activated(int)'),
66 self.onBackgroundTypeComboBoxSelected)66 self.onBackgroundTypeComboBoxSelected)
67 QtCore.QObject.connect(self.GradientComboBox,67 QtCore.QObject.connect(self.GradientComboBox,
68 QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)68 QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)
69 QtCore.QObject.connect(self.FontMainComboBox,69 QtCore.QObject.connect(self.FontMainComboBox,
70 QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)70 QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)
71 QtCore.QObject.connect(self.FontMainWeightComboBox,71 QtCore.QObject.connect(self.FontMainWeightComboBox,
72 QtCore.SIGNAL(u'activated(int)'),72 QtCore.SIGNAL(u'activated(int)'),
73 self.onFontMainWeightComboBoxSelected)73 self.onFontMainWeightComboBoxSelected)
74 QtCore.QObject.connect(self.FontFooterComboBox,74 QtCore.QObject.connect(self.FontFooterComboBox,
75 QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)75 QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)
76 QtCore.QObject.connect(self.FontFooterWeightComboBox,76 QtCore.QObject.connect(self.FontFooterWeightComboBox,
77 QtCore.SIGNAL(u'activated(int)'),77 QtCore.SIGNAL(u'activated(int)'),
78 self.onFontFooterWeightComboBoxSelected)78 self.onFontFooterWeightComboBoxSelected)
79 QtCore.QObject.connect(self.HorizontalComboBox,79 QtCore.QObject.connect(self.HorizontalComboBox,
80 QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)80 QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)
81 QtCore.QObject.connect(self.VerticalComboBox,81 QtCore.QObject.connect(self.VerticalComboBox,
82 QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)82 QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)
83 #Spin boxes83 #Spin boxes
84 QtCore.QObject.connect(self.FontMainSizeSpinBox,84 QtCore.QObject.connect(self.FontMainSizeSpinBox,
85 QtCore.SIGNAL(u'editingFinished()'),85 QtCore.SIGNAL(u'editingFinished()'),
86 self.onFontMainSizeSpinBoxChanged)86 self.onFontMainSizeSpinBoxChanged)
87 QtCore.QObject.connect(self.FontFooterSizeSpinBox,87 QtCore.QObject.connect(self.FontFooterSizeSpinBox,
88 QtCore.SIGNAL(u'editingFinished()'),88 QtCore.SIGNAL(u'editingFinished()'),
89 self.onFontFooterSizeSpinBoxChanged)89 self.onFontFooterSizeSpinBoxChanged)
90 QtCore.QObject.connect(self.FontMainDefaultCheckBox,90 QtCore.QObject.connect(self.FontMainDefaultCheckBox,
91 QtCore.SIGNAL(u'stateChanged(int)'),91 QtCore.SIGNAL(u'stateChanged(int)'),
92 self.onFontMainDefaultCheckBoxChanged)92 self.onFontMainDefaultCheckBoxChanged)
93 QtCore.QObject.connect(self.FontMainXSpinBox,93 QtCore.QObject.connect(self.FontMainXSpinBox,
94 QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)94 QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)
95 QtCore.QObject.connect(self.FontMainYSpinBox,95 QtCore.QObject.connect(self.FontMainYSpinBox,
96 QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)96 QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)
97 QtCore.QObject.connect(self.FontMainWidthSpinBox,97 QtCore.QObject.connect(self.FontMainWidthSpinBox,
98 QtCore.SIGNAL(u'editingFinished()'),98 QtCore.SIGNAL(u'editingFinished()'),
99 self.onFontMainWidthSpinBoxChanged)99 self.onFontMainWidthSpinBoxChanged)
100 QtCore.QObject.connect(self.FontMainHeightSpinBox,100 QtCore.QObject.connect(self.FontMainHeightSpinBox,
101 QtCore.SIGNAL(u'editingFinished()'),101 QtCore.SIGNAL(u'editingFinished()'),
102 self.onFontMainHeightSpinBoxChanged)102 self.onFontMainHeightSpinBoxChanged)
103 QtCore.QObject.connect(self.FontFooterDefaultCheckBox,103 QtCore.QObject.connect(self.FontFooterDefaultCheckBox,
104 QtCore.SIGNAL(u'stateChanged(int)'),104 QtCore.SIGNAL(u'stateChanged(int)'),
105 self.onFontFooterDefaultCheckBoxChanged)105 self.onFontFooterDefaultCheckBoxChanged)
106 QtCore.QObject.connect(self.FontFooterXSpinBox,106 QtCore.QObject.connect(self.FontFooterXSpinBox,
107 QtCore.SIGNAL(u'editingFinished()'),107 QtCore.SIGNAL(u'editingFinished()'),
108 self.onFontFooterXSpinBoxChanged)108 self.onFontFooterXSpinBoxChanged)
109 QtCore.QObject.connect(self.FontFooterYSpinBox,109 QtCore.QObject.connect(self.FontFooterYSpinBox,
110 QtCore.SIGNAL(u'editingFinished()'),110 QtCore.SIGNAL(u'editingFinished()'),
111 self.onFontFooterYSpinBoxChanged)111 self.onFontFooterYSpinBoxChanged)
112 QtCore.QObject.connect(self.FontFooterWidthSpinBox,112 QtCore.QObject.connect(self.FontFooterWidthSpinBox,
113 QtCore.SIGNAL(u'editingFinished()'),113 QtCore.SIGNAL(u'editingFinished()'),
114 self.onFontFooterWidthSpinBoxChanged)114 self.onFontFooterWidthSpinBoxChanged)
115 QtCore.QObject.connect(self.FontFooterHeightSpinBox,115 QtCore.QObject.connect(self.FontFooterHeightSpinBox,
116 QtCore.SIGNAL(u'editingFinished()'),116 QtCore.SIGNAL(u'editingFinished()'),
117 self.onFontFooterHeightSpinBoxChanged)117 self.onFontFooterHeightSpinBoxChanged)
118 QtCore.QObject.connect(self.OutlineCheckBox,118 QtCore.QObject.connect(self.OutlineCheckBox,
119 QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)119 QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)
120 QtCore.QObject.connect(self.ShadowCheckBox,120 QtCore.QObject.connect(self.ShadowCheckBox,
121 QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged)121 QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged)
122122
123 def accept(self):123 def accept(self):
124 new_theme = ThemeXML()124 new_theme = ThemeXML()
125 theme_name = unicode(self.ThemeNameEdit.displayText())125 theme_name = unicode(self.ThemeNameEdit.displayText())
126 new_theme.new_document(theme_name)126 new_theme.new_document(theme_name)
127 save_from = None127 save_from = None
128 save_to = None128 save_to = None
129 if self.theme.background_mode == u'transparent':129 if self.theme.background_mode == u'transparent':
130 new_theme.add_background_transparent()130 new_theme.add_background_transparent()
131 else:131 else:
132 if self.theme.background_type == u'solid':132 if self.theme.background_type == u'solid':
133 new_theme.add_background_solid( \133 new_theme.add_background_solid( \
134 unicode(self.theme.background_color))134 unicode(self.theme.background_color))
135 elif self.theme.background_type == u'gradient':135 elif self.theme.background_type == u'gradient':
136 new_theme.add_background_gradient( \136 new_theme.add_background_gradient( \
137 unicode(self.theme.background_startColor),137 unicode(self.theme.background_startColor),
138 unicode(self.theme.background_endColor),138 unicode(self.theme.background_endColor),
139 self.theme.background_direction)139 self.theme.background_direction)
140 else:140 else:
141 (path, filename) = \141 (path, filename) = \
142 os.path.split(unicode(self.theme.background_filename))142 os.path.split(unicode(self.theme.background_filename))
143 new_theme.add_background_image(filename)143 new_theme.add_background_image(filename)
144 save_to= os.path.join(self.path, theme_name, filename )144 save_to= os.path.join(self.path, theme_name, filename )
145 save_from = self.theme.background_filename145 save_from = self.theme.background_filename
146146
147 new_theme.add_font(unicode(self.theme.font_main_name),147 new_theme.add_font(unicode(self.theme.font_main_name),
148 unicode(self.theme.font_main_color),148 unicode(self.theme.font_main_color),
149 unicode(self.theme.font_main_proportion),149 unicode(self.theme.font_main_proportion),
150 unicode(self.theme.font_main_override), u'main',150 unicode(self.theme.font_main_override), u'main',
151 unicode(self.theme.font_main_weight),151 unicode(self.theme.font_main_weight),
152 unicode(self.theme.font_main_italics),152 unicode(self.theme.font_main_italics),
153 unicode(self.theme.font_main_x),153 unicode(self.theme.font_main_x),
154 unicode(self.theme.font_main_y),154 unicode(self.theme.font_main_y),
155 unicode(self.theme.font_main_width),155 unicode(self.theme.font_main_width),
156 unicode(self.theme.font_main_height))156 unicode(self.theme.font_main_height))
157 new_theme.add_font(unicode(self.theme.font_footer_name),157 new_theme.add_font(unicode(self.theme.font_footer_name),
158 unicode(self.theme.font_footer_color),158 unicode(self.theme.font_footer_color),
159 unicode(self.theme.font_footer_proportion),159 unicode(self.theme.font_footer_proportion),
160 unicode(self.theme.font_footer_override), u'footer',160 unicode(self.theme.font_footer_override), u'footer',
161 unicode(self.theme.font_footer_weight),161 unicode(self.theme.font_footer_weight),
162 unicode(self.theme.font_footer_italics),162 unicode(self.theme.font_footer_italics),
163 unicode(self.theme.font_footer_x),163 unicode(self.theme.font_footer_x),
164 unicode(self.theme.font_footer_y),164 unicode(self.theme.font_footer_y),
165 unicode(self.theme.font_footer_width),165 unicode(self.theme.font_footer_width),
166 unicode(self.theme.font_footer_height) )166 unicode(self.theme.font_footer_height) )
167 new_theme.add_display(unicode(self.theme.display_shadow),167 new_theme.add_display(unicode(self.theme.display_shadow),
168 unicode(self.theme.display_shadow_color),168 unicode(self.theme.display_shadow_color),
169 unicode(self.theme.display_outline),169 unicode(self.theme.display_outline),
170 unicode(self.theme.display_outline_color),170 unicode(self.theme.display_outline_color),
171 unicode(self.theme.display_horizontalAlign),171 unicode(self.theme.display_horizontalAlign),
172 unicode(self.theme.display_verticalAlign),172 unicode(self.theme.display_verticalAlign),
173 unicode(self.theme.display_wrapStyle))173 unicode(self.theme.display_wrapStyle))
174 theme = new_theme.extract_xml()174 theme = new_theme.extract_xml()
175 pretty_theme = new_theme.extract_formatted_xml()175 pretty_theme = new_theme.extract_formatted_xml()
176 if self.thememanager.saveTheme(theme_name, theme, pretty_theme,176 if self.thememanager.saveTheme(theme_name, theme, pretty_theme,
177 save_from, save_to) is not False:177 save_from, save_to) is not False:
178 return QtGui.QDialog.accept(self)178 return QtGui.QDialog.accept(self)
179179
180 def loadTheme(self, theme):180 def loadTheme(self, theme):
181 log.debug(u'LoadTheme %s', theme)181 log.debug(u'LoadTheme %s', theme)
182 if theme == None:182 if theme == None:
183 self.theme.parse(self.baseTheme())183 self.theme.parse(self.baseTheme())
184 else:184 else:
185 xml_file = os.path.join(self.path, theme, theme + u'.xml')185 xml_file = os.path.join(self.path, theme, theme + u'.xml')
186 xml = file_to_xml(xml_file)186 xml = file_to_xml(xml_file)
187 self.theme.parse(xml)187 self.theme.parse(xml)
188 self.theme.extend_image_filename(self.path)188 self.theme.extend_image_filename(self.path)
189 self.cleanTheme(self.theme)189 self.cleanTheme(self.theme)
190 self.allowPreview = False190 self.allowPreview = False
191 self.paintUi(self.theme)191 self.paintUi(self.theme)
192 self.allowPreview = True192 self.allowPreview = True
193 self.previewTheme(self.theme)193 self.previewTheme(self.theme)
194194
195 def cleanTheme(self, theme):195 def cleanTheme(self, theme):
196 self.theme.background_color = theme.background_color.strip()196 self.theme.background_color = theme.background_color.strip()
197 self.theme.background_direction = theme.background_direction.strip()197 self.theme.background_direction = theme.background_direction.strip()
198 self.theme.background_endColor = theme.background_endColor.strip()198 self.theme.background_endColor = theme.background_endColor.strip()
199 if theme.background_filename:199 if theme.background_filename:
200 self.theme.background_filename = theme.background_filename.strip()200 self.theme.background_filename = theme.background_filename.strip()
201 #self.theme.background_mode201 #self.theme.background_mode
202 self.theme.background_startColor = theme.background_startColor.strip()202 self.theme.background_startColor = theme.background_startColor.strip()
203 #self.theme.background_type203 #self.theme.background_type
204 if theme.display_display:204 if theme.display_display:
205 self.theme.display_display = theme.display_display.strip()205 self.theme.display_display = theme.display_display.strip()
206 self.theme.display_horizontalAlign = \206 self.theme.display_horizontalAlign = \
207 theme.display_horizontalAlign.strip()207 theme.display_horizontalAlign.strip()
208 self.theme.display_outline = str_to_bool(theme.display_outline)208 self.theme.display_outline = str_to_bool(theme.display_outline)
209 #self.theme.display_outline_color209 #self.theme.display_outline_color
210 self.theme.display_shadow = str_to_bool(theme.display_shadow)210 self.theme.display_shadow = str_to_bool(theme.display_shadow)
211 #self.theme.display_shadow_color211 #self.theme.display_shadow_color
212 self.theme.display_verticalAlign = \212 self.theme.display_verticalAlign = \
213 theme.display_verticalAlign.strip()213 theme.display_verticalAlign.strip()
214 self.theme.display_wrapStyle = theme.display_wrapStyle.strip()214 self.theme.display_wrapStyle = theme.display_wrapStyle.strip()
215 self.theme.font_footer_color = theme.font_footer_color.strip()215 self.theme.font_footer_color = theme.font_footer_color.strip()
216 self.theme.font_footer_height = theme.font_footer_height.strip()216 self.theme.font_footer_height = theme.font_footer_height.strip()
217 self.theme.font_footer_italics = str_to_bool(theme.font_footer_italics)217 self.theme.font_footer_italics = str_to_bool(theme.font_footer_italics)
218 self.theme.font_footer_name = theme.font_footer_name.strip()218 self.theme.font_footer_name = theme.font_footer_name.strip()
219 #self.theme.font_footer_override219 #self.theme.font_footer_override
220 self.theme.font_footer_proportion = \220 self.theme.font_footer_proportion = \
221 theme.font_footer_proportion.strip()221 theme.font_footer_proportion.strip()
222 self.theme.font_footer_weight = theme.font_footer_weight.strip()222 self.theme.font_footer_weight = theme.font_footer_weight.strip()
223 self.theme.font_footer_width = theme.font_footer_width.strip()223 self.theme.font_footer_width = theme.font_footer_width.strip()
224 self.theme.font_footer_x = theme.font_footer_x.strip()224 self.theme.font_footer_x = theme.font_footer_x.strip()
225 self.theme.font_footer_y = theme.font_footer_y.strip()225 self.theme.font_footer_y = theme.font_footer_y.strip()
226 self.theme.font_main_color = theme.font_main_color.strip()226 self.theme.font_main_color = theme.font_main_color.strip()
227 self.theme.font_main_height = theme.font_main_height.strip()227 self.theme.font_main_height = theme.font_main_height.strip()
228 self.theme.font_main_italics = str_to_bool(theme.font_main_italics)228 self.theme.font_main_italics = str_to_bool(theme.font_main_italics)
229 self.theme.font_main_name = theme.font_main_name.strip()229 self.theme.font_main_name = theme.font_main_name.strip()
230 #self.theme.font_main_override230 #self.theme.font_main_override
231 self.theme.font_main_proportion = theme.font_main_proportion.strip()231 self.theme.font_main_proportion = theme.font_main_proportion.strip()
232 self.theme.font_main_weight = theme.font_main_weight.strip()232 self.theme.font_main_weight = theme.font_main_weight.strip()
233 self.theme.font_main_x = theme.font_main_x.strip()233 self.theme.font_main_x = theme.font_main_x.strip()
234 self.theme.font_main_y = theme.font_main_y.strip()234 self.theme.font_main_y = theme.font_main_y.strip()
235 #self.theme.theme_mode235 #self.theme.theme_mode
236 self.theme.theme_name = theme.theme_name.strip()236 self.theme.theme_name = theme.theme_name.strip()
237 #self.theme.theme_version237 #self.theme.theme_version
238238
239 def onImageToolButtonClicked(self):239 def onImageToolButtonClicked(self):
240 filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file')240 filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file')
241 if filename != "":241 if filename != "":
242 self.ImageLineEdit.setText(filename)242 self.ImageLineEdit.setText(filename)
243 self.theme.background_filename = filename243 self.theme.background_filename = filename
244 self.previewTheme(self.theme)244 self.previewTheme(self.theme)
245 #245 #
246 #Main Font Tab246 #Main Font Tab
247 #247 #
248 def onFontMainComboBoxSelected(self):248 def onFontMainComboBoxSelected(self):
249 self.theme.font_main_name = self.FontMainComboBox.currentFont().family()249 self.theme.font_main_name = self.FontMainComboBox.currentFont().family()
250 self.previewTheme(self.theme)250 self.previewTheme(self.theme)
251251
252 def onFontMainWeightComboBoxSelected(self, value):252 def onFontMainWeightComboBoxSelected(self, value):
253 if value ==0:253 if value ==0:
254 self.theme.font_main_weight = u'Normal'254 self.theme.font_main_weight = u'Normal'
255 self.theme.font_main_italics = False255 self.theme.font_main_italics = False
256 elif value == 1:256 elif value == 1:
257 self.theme.font_main_weight = u'Bold'257 self.theme.font_main_weight = u'Bold'
258 self.theme.font_main_italics = False258 self.theme.font_main_italics = False
259 elif value == 2:259 elif value == 2:
260 self.theme.font_main_weight = u'Normal'260 self.theme.font_main_weight = u'Normal'
261 self.theme.font_main_italics = True261 self.theme.font_main_italics = True
262 else:262 else:
263 self.theme.font_main_weight = u'Bold'263 self.theme.font_main_weight = u'Bold'
264 self.theme.font_main_italics = True264 self.theme.font_main_italics = True
265 self.previewTheme(self.theme)265 self.previewTheme(self.theme)
266266
267 def onFontMainColorPushButtonClicked(self):267 def onFontMainColorPushButtonClicked(self):
268 self.theme.font_main_color = QtGui.QColorDialog.getColor(268 self.theme.font_main_color = QtGui.QColorDialog.getColor(
269 QtGui.QColor(self.theme.font_main_color), self).name()269 QtGui.QColor(self.theme.font_main_color), self).name()
270270
271 self.FontMainColorPushButton.setStyleSheet(271 self.FontMainColorPushButton.setStyleSheet(
272 u'background-color: %s' % unicode(self.theme.font_main_color))272 u'background-color: %s' % unicode(self.theme.font_main_color))
273 self.previewTheme(self.theme)273 self.previewTheme(self.theme)
274274
275 def onFontMainSizeSpinBoxChanged(self):275 def onFontMainSizeSpinBoxChanged(self):
276 if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value():276 if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value():
277 self.theme.font_main_proportion = self.FontMainSizeSpinBox.value()277 self.theme.font_main_proportion = self.FontMainSizeSpinBox.value()
278 self.previewTheme(self.theme)278 self.previewTheme(self.theme)
279279
280 def onFontMainDefaultCheckBoxChanged(self, value):280 def onFontMainDefaultCheckBoxChanged(self, value):
281 if value == 2: # checked281 if value == 2: # checked
282 self.theme.font_main_override = False282 self.theme.font_main_override = False
283 else:283 else:
284 self.theme.font_main_override = True284 self.theme.font_main_override = True
285285
286 if int(self.theme.font_main_x) == 0 and \286 if int(self.theme.font_main_x) == 0 and \
287 int(self.theme.font_main_y) == 0 and \287 int(self.theme.font_main_y) == 0 and \
288 int(self.theme.font_main_width) == 0 and \288 int(self.theme.font_main_width) == 0 and \
289 int(self.theme.font_main_height) == 0:289 int(self.theme.font_main_height) == 0:
290 self.theme.font_main_x = u'10'290 self.theme.font_main_x = u'10'
291 self.theme.font_main_y = u'10'291 self.theme.font_main_y = u'10'
292 self.theme.font_main_width = u'1024'292 self.theme.font_main_width = u'1024'
293 self.theme.font_main_height = u'730'293 self.theme.font_main_height = u'730'
294 self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))294 self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
295 self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))295 self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
296 self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))296 self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
297 self.FontMainHeightSpinBox.setValue(int( \297 self.FontMainHeightSpinBox.setValue(int( \
298 self.theme.font_main_height))298 self.theme.font_main_height))
299 self.stateChanging(self.theme)299 self.stateChanging(self.theme)
300 self.previewTheme(self.theme)300 self.previewTheme(self.theme)
301301
302 def onFontMainXSpinBoxChanged(self):302 def onFontMainXSpinBoxChanged(self):
303 if self.theme.font_main_x != self.FontMainXSpinBox.value():303 if self.theme.font_main_x != self.FontMainXSpinBox.value():
304 self.theme.font_main_x = self.FontMainXSpinBox.value()304 self.theme.font_main_x = self.FontMainXSpinBox.value()
305 self.previewTheme(self.theme)305 self.previewTheme(self.theme)
306306
307 def onFontMainYSpinBoxChanged(self):307 def onFontMainYSpinBoxChanged(self):
308 if self.theme.font_main_y != self.FontMainYSpinBox.value():308 if self.theme.font_main_y != self.FontMainYSpinBox.value():
309 self.theme.font_main_y = self.FontMainYSpinBox.value()309 self.theme.font_main_y = self.FontMainYSpinBox.value()
310 self.previewTheme(self.theme)310 self.previewTheme(self.theme)
311311
312 def onFontMainWidthSpinBoxChanged(self):312 def onFontMainWidthSpinBoxChanged(self):
313 if self.theme.font_main_width != self.FontMainWidthSpinBox.value():313 if self.theme.font_main_width != self.FontMainWidthSpinBox.value():
314 self.theme.font_main_width = self.FontMainWidthSpinBox.value()314 self.theme.font_main_width = self.FontMainWidthSpinBox.value()
315 self.previewTheme(self.theme)315 self.previewTheme(self.theme)
316316
317 def onFontMainHeightSpinBoxChanged(self):317 def onFontMainHeightSpinBoxChanged(self):
318 if self.theme.font_main_height != self.FontMainHeightSpinBox.value():318 if self.theme.font_main_height != self.FontMainHeightSpinBox.value():
319 self.theme.font_main_height = self.FontMainHeightSpinBox.value()319 self.theme.font_main_height = self.FontMainHeightSpinBox.value()
320 self.previewTheme(self.theme)320 self.previewTheme(self.theme)
321 #321 #
322 #Footer Font Tab322 #Footer Font Tab
323 #323 #
324 def onFontFooterComboBoxSelected(self):324 def onFontFooterComboBoxSelected(self):
325 self.theme.font_footer_name = \325 self.theme.font_footer_name = \
326 self.FontFooterComboBox.currentFont().family()326 self.FontFooterComboBox.currentFont().family()
327 self.previewTheme(self.theme)327 self.previewTheme(self.theme)
328328
329 def onFontFooterWeightComboBoxSelected(self, value):329 def onFontFooterWeightComboBoxSelected(self, value):
330 if value == 0:330 if value == 0:
331 self.theme.font_footer_weight = u'Normal'331 self.theme.font_footer_weight = u'Normal'
332 self.theme.font_footer_italics = False332 self.theme.font_footer_italics = False
333 elif value == 1:333 elif value == 1:
334 self.theme.font_footer_weight = u'Bold'334 self.theme.font_footer_weight = u'Bold'
335 self.theme.font_footer_italics = False335 self.theme.font_footer_italics = False
336 elif value == 2:336 elif value == 2:
337 self.theme.font_footer_weight = u'Normal'337 self.theme.font_footer_weight = u'Normal'
338 self.theme.font_footer_italics = True338 self.theme.font_footer_italics = True
339 else:339 else:
340 self.theme.font_footer_weight = u'Bold'340 self.theme.font_footer_weight = u'Bold'
341 self.theme.font_footer_italics = True341 self.theme.font_footer_italics = True
342 self.previewTheme(self.theme)342 self.previewTheme(self.theme)
343343
344 def onFontFooterColorPushButtonClicked(self):344 def onFontFooterColorPushButtonClicked(self):
345 self.theme.font_footer_color = QtGui.QColorDialog.getColor(345 self.theme.font_footer_color = QtGui.QColorDialog.getColor(
346 QtGui.QColor(self.theme.font_footer_color), self).name()346 QtGui.QColor(self.theme.font_footer_color), self).name()
347347
348 self.FontFooterColorPushButton.setStyleSheet(348 self.FontFooterColorPushButton.setStyleSheet(
349 'background-color: %s' % unicode(self.theme.font_footer_color))349 'background-color: %s' % unicode(self.theme.font_footer_color))
350 self.previewTheme(self.theme)350 self.previewTheme(self.theme)
351351
352 def onFontFooterSizeSpinBoxChanged(self):352 def onFontFooterSizeSpinBoxChanged(self):
353 if self.theme.font_footer_proportion != \353 if self.theme.font_footer_proportion != \
354 self.FontFooterSizeSpinBox.value():354 self.FontFooterSizeSpinBox.value():
355 self.theme.font_footer_proportion = \355 self.theme.font_footer_proportion = \
356 self.FontFooterSizeSpinBox.value()356 self.FontFooterSizeSpinBox.value()
357 self.previewTheme(self.theme)357 self.previewTheme(self.theme)
358358
359 def onFontFooterDefaultCheckBoxChanged(self, value):359 def onFontFooterDefaultCheckBoxChanged(self, value):
360 if value == 2: # checked360 if value == 2: # checked
361 self.theme.font_footer_override = False361 self.theme.font_footer_override = False
362 else:362 else:
363 self.theme.font_footer_override = True363 self.theme.font_footer_override = True
364364
365 if int(self.theme.font_footer_x) == 0 and \365 if int(self.theme.font_footer_x) == 0 and \
366 int(self.theme.font_footer_y) == 0 and \366 int(self.theme.font_footer_y) == 0 and \
367 int(self.theme.font_footer_width) == 0 and \367 int(self.theme.font_footer_width) == 0 and \
368 int(self.theme.font_footer_height) == 0:368 int(self.theme.font_footer_height) == 0:
369 self.theme.font_footer_x = u'10'369 self.theme.font_footer_x = u'10'
370 self.theme.font_footer_y = u'730'370 self.theme.font_footer_y = u'730'
371 self.theme.font_footer_width = u'1024'371 self.theme.font_footer_width = u'1024'
372 self.theme.font_footer_height = u'38'372 self.theme.font_footer_height = u'38'
373373
374 self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))374 self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
375 self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))375 self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
376 self.FontFooterWidthSpinBox.setValue(int( \376 self.FontFooterWidthSpinBox.setValue(int( \
377 self.theme.font_footer_width))377 self.theme.font_footer_width))
378 self.FontFooterHeightSpinBox.setValue(int( \378 self.FontFooterHeightSpinBox.setValue(int( \
379 self.theme.font_footer_height))379 self.theme.font_footer_height))
380380
381 self.stateChanging(self.theme)381 self.stateChanging(self.theme)
382 self.previewTheme(self.theme)382 self.previewTheme(self.theme)
383383
384 def onFontFooterXSpinBoxChanged(self):384 def onFontFooterXSpinBoxChanged(self):
385 if self.theme.font_footer_x != self.FontFooterXSpinBox.value():385 if self.theme.font_footer_x != self.FontFooterXSpinBox.value():
386 self.theme.font_footer_x = self.FontFooterXSpinBox.value()386 self.theme.font_footer_x = self.FontFooterXSpinBox.value()
387 self.previewTheme(self.theme)387 self.previewTheme(self.theme)
388388
389 def onFontFooterYSpinBoxChanged(self):389 def onFontFooterYSpinBoxChanged(self):
390 if self.theme.font_footer_y != self.FontFooterYSpinBox.value():390 if self.theme.font_footer_y != self.FontFooterYSpinBox.value():
391 self.theme.font_footer_y = self.FontFooterYSpinBox.value()391 self.theme.font_footer_y = self.FontFooterYSpinBox.value()
392 self.previewTheme(self.theme)392 self.previewTheme(self.theme)
393393
394 def onFontFooterWidthSpinBoxChanged(self):394 def onFontFooterWidthSpinBoxChanged(self):
395 if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value():395 if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value():
396 self.theme.font_footer_width = self.FontFooterWidthSpinBox.value()396 self.theme.font_footer_width = self.FontFooterWidthSpinBox.value()
397 self.previewTheme(self.theme)397 self.previewTheme(self.theme)
398398
399 def onFontFooterHeightSpinBoxChanged(self):399 def onFontFooterHeightSpinBoxChanged(self):
400 if self.theme.font_footer_height != \400 if self.theme.font_footer_height != \
401 self.FontFooterHeightSpinBox.value():401 self.FontFooterHeightSpinBox.value():
402 self.theme.font_footer_height = self.FontFooterHeightSpinBox.value()402 self.theme.font_footer_height = self.FontFooterHeightSpinBox.value()
403 self.previewTheme(self.theme)403 self.previewTheme(self.theme)
404 #404 #
405 #Background Tab405 #Background Tab
406 #406 #
407 def onGradientComboBoxSelected(self, currentIndex):407 def onGradientComboBoxSelected(self, currentIndex):
408 self.setBackground(self.BackgroundTypeComboBox.currentIndex(),408 self.setBackground(self.BackgroundTypeComboBox.currentIndex(),
409 currentIndex)409 currentIndex)
410410
411 def onBackgroundComboBoxSelected(self, currentIndex):411 def onBackgroundComboBoxSelected(self, currentIndex):
412 if currentIndex == 0: # Opaque412 if currentIndex == 0: # Opaque
413 self.theme.background_mode = u'opaque'413 self.theme.background_mode = u'opaque'
414 else:414 else:
415 self.theme.background_mode = u'transparent'415 self.theme.background_mode = u'transparent'
416 self.stateChanging(self.theme)416 self.stateChanging(self.theme)
417 self.previewTheme(self.theme)417 self.previewTheme(self.theme)
418418
419 def onBackgroundTypeComboBoxSelected(self, currentIndex):419 def onBackgroundTypeComboBoxSelected(self, currentIndex):
420 self.setBackground(currentIndex, self.GradientComboBox.currentIndex())420 self.setBackground(currentIndex, self.GradientComboBox.currentIndex())
421421
422 def setBackground(self, background, gradient):422 def setBackground(self, background, gradient):
423 if background == 0: # Solid423 if background == 0: # Solid
424 self.theme.background_type = u'solid'424 self.theme.background_type = u'solid'
425 if self.theme.background_color is None :425 if self.theme.background_color is None :
426 self.theme.background_color = u'#000000'426 self.theme.background_color = u'#000000'
427 elif background == 1: # Gradient427 elif background == 1: # Gradient
428 self.theme.background_type = u'gradient'428 self.theme.background_type = u'gradient'
429 if gradient == 0: # Horizontal429 if gradient == 0: # Horizontal
430 self.theme.background_direction = u'horizontal'430 self.theme.background_direction = u'horizontal'
431 elif gradient == 1: # vertical431 elif gradient == 1: # vertical
432 self.theme.background_direction = u'vertical'432 self.theme.background_direction = u'vertical'
433 else:433 else:
434 self.theme.background_direction = u'circular'434 self.theme.background_direction = u'circular'
435 if self.theme.background_startColor is None :435 if self.theme.background_startColor is None :
436 self.theme.background_startColor = u'#000000'436 self.theme.background_startColor = u'#000000'
437 if self.theme.background_endColor is None :437 if self.theme.background_endColor is None :
438 self.theme.background_endColor = u'#ff0000'438 self.theme.background_endColor = u'#ff0000'
439 else:439 else:
440 self.theme.background_type = u'image'440 self.theme.background_type = u'image'
441 self.stateChanging(self.theme)441 self.stateChanging(self.theme)
442 self.previewTheme(self.theme)442 self.previewTheme(self.theme)
443443
444 def onColor1PushButtonClicked(self):444 def onColor1PushButtonClicked(self):
445 if self.theme.background_type == u'solid':445 if self.theme.background_type == u'solid':
446 self.theme.background_color = QtGui.QColorDialog.getColor(446 self.theme.background_color = QtGui.QColorDialog.getColor(
447 QtGui.QColor(self.theme.background_color), self).name()447 QtGui.QColor(self.theme.background_color), self).name()
448 self.Color1PushButton.setStyleSheet(448 self.Color1PushButton.setStyleSheet(
449 u'background-color: %s' % unicode(self.theme.background_color))449 u'background-color: %s' % unicode(self.theme.background_color))
450 else:450 else:
451 self.theme.background_startColor = QtGui.QColorDialog.getColor(451 self.theme.background_startColor = QtGui.QColorDialog.getColor(
452 QtGui.QColor(self.theme.background_startColor), self).name()452 QtGui.QColor(self.theme.background_startColor), self).name()
453 self.Color1PushButton.setStyleSheet(453 self.Color1PushButton.setStyleSheet(
454 u'background-color: %s' % \454 u'background-color: %s' % \
455 unicode(self.theme.background_startColor))455 unicode(self.theme.background_startColor))
456456
457 self.previewTheme(self.theme)457 self.previewTheme(self.theme)
458458
459 def onColor2PushButtonClicked(self):459 def onColor2PushButtonClicked(self):
460 self.theme.background_endColor = QtGui.QColorDialog.getColor(460 self.theme.background_endColor = QtGui.QColorDialog.getColor(
461 QtGui.QColor(self.theme.background_endColor), self).name()461 QtGui.QColor(self.theme.background_endColor), self).name()
462 self.Color2PushButton.setStyleSheet(462 self.Color2PushButton.setStyleSheet(
463 u'background-color: %s' % unicode(self.theme.background_endColor))463 u'background-color: %s' % unicode(self.theme.background_endColor))
464464
465 self.previewTheme(self.theme)465 self.previewTheme(self.theme)
466 #466 #
467 #Other Tab467 #Other Tab
468 #468 #
469 def onOutlineCheckBoxChanged(self, value):469 def onOutlineCheckBoxChanged(self, value):
470 if value == 2: # checked470 if value == 2: # checked
471 self.theme.display_outline = True471 self.theme.display_outline = True
472 else:472 else:
473 self.theme.display_outline = False473 self.theme.display_outline = False
474 self.stateChanging(self.theme)474 self.stateChanging(self.theme)
475 self.previewTheme(self.theme)475 self.previewTheme(self.theme)
476476
477 def onOutlineColorPushButtonClicked(self):477 def onOutlineColorPushButtonClicked(self):
478 self.theme.display_outline_color = QtGui.QColorDialog.getColor(478 self.theme.display_outline_color = QtGui.QColorDialog.getColor(
479 QtGui.QColor(self.theme.display_outline_color), self).name()479 QtGui.QColor(self.theme.display_outline_color), self).name()
480 self.OutlineColorPushButton.setStyleSheet(480 self.OutlineColorPushButton.setStyleSheet(
481 u'background-color: %s' % unicode(self.theme.display_outline_color))481 u'background-color: %s' % unicode(self.theme.display_outline_color))
482 self.previewTheme(self.theme)482 self.previewTheme(self.theme)
483483
484 def onShadowCheckBoxChanged(self, value):484 def onShadowCheckBoxChanged(self, value):
485 if value == 2: # checked485 if value == 2: # checked
486 self.theme.display_shadow = True486 self.theme.display_shadow = True
487 else:487 else:
488 self.theme.display_shadow = False488 self.theme.display_shadow = False
489 self.stateChanging(self.theme)489 self.stateChanging(self.theme)
490 self.previewTheme(self.theme)490 self.previewTheme(self.theme)
491491
492 def onShadowColorPushButtonClicked(self):492 def onShadowColorPushButtonClicked(self):
493 self.theme.display_shadow_color = QtGui.QColorDialog.getColor(493 self.theme.display_shadow_color = QtGui.QColorDialog.getColor(
494 QtGui.QColor(self.theme.display_shadow_color), self).name()494 QtGui.QColor(self.theme.display_shadow_color), self).name()
495 self.ShadowColorPushButton.setStyleSheet(495 self.ShadowColorPushButton.setStyleSheet(
496 u'background-color: %s' % unicode(self.theme.display_shadow_color))496 u'background-color: %s' % unicode(self.theme.display_shadow_color))
497 self.previewTheme(self.theme)497 self.previewTheme(self.theme)
498498
499 def onHorizontalComboBoxSelected(self, currentIndex):499 def onHorizontalComboBoxSelected(self, currentIndex):
500 self.theme.display_horizontalAlign = currentIndex500 self.theme.display_horizontalAlign = currentIndex
501 self.stateChanging(self.theme)501 self.stateChanging(self.theme)
502 self.previewTheme(self.theme)502 self.previewTheme(self.theme)
503503
504 def onVerticalComboBoxSelected(self, currentIndex):504 def onVerticalComboBoxSelected(self, currentIndex):
505 self.theme.display_verticalAlign = currentIndex505 self.theme.display_verticalAlign = currentIndex
506 self.stateChanging(self.theme)506 self.stateChanging(self.theme)
507 self.previewTheme(self.theme)507 self.previewTheme(self.theme)
508 #508 #
509 #Local Methods509 #Local Methods
510 #510 #
511 def baseTheme(self):511 def baseTheme(self):
512 log.debug(u'base theme created')512 log.debug(u'base theme created')
513 newtheme = ThemeXML()513 newtheme = ThemeXML()
514 newtheme.new_document(u'New Theme')514 newtheme.new_document(u'New Theme')
515 newtheme.add_background_solid(unicode(u'#000000'))515 newtheme.add_background_solid(unicode(u'#000000'))
516 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),516 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
517 unicode(30), u'False')517 unicode(30), u'False')
518 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),518 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
519 unicode(12), u'False', u'footer')519 unicode(12), u'False', u'footer')
520 newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',520 newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
521 unicode(u'#FFFFFF'),521 unicode(u'#FFFFFF'),
522 unicode(0), unicode(0), unicode(0))522 unicode(0), unicode(0), unicode(0))
523523
524 return newtheme.extract_xml()524 return newtheme.extract_xml()
525525
526 def paintUi(self, theme):526 def paintUi(self, theme):
527 self.stateChanging(theme)527 self.stateChanging(theme)
528 self.ThemeNameEdit.setText(self.theme.theme_name)528 self.ThemeNameEdit.setText(self.theme.theme_name)
529 if self.theme.background_mode == u'opaque':529 if self.theme.background_mode == u'opaque':
530 self.BackgroundComboBox.setCurrentIndex(0)530 self.BackgroundComboBox.setCurrentIndex(0)
531 else:531 else:
532 self.BackgroundComboBox.setCurrentIndex(1)532 self.BackgroundComboBox.setCurrentIndex(1)
533533
534 if theme.background_type == u'solid':534 if theme.background_type == u'solid':
535 self.BackgroundTypeComboBox.setCurrentIndex(0)535 self.BackgroundTypeComboBox.setCurrentIndex(0)
536 elif theme.background_type == u'gradient':536 elif theme.background_type == u'gradient':
537 self.BackgroundTypeComboBox.setCurrentIndex(1)537 self.BackgroundTypeComboBox.setCurrentIndex(1)
538 else:538 else:
539 self.BackgroundTypeComboBox.setCurrentIndex(2)539 self.BackgroundTypeComboBox.setCurrentIndex(2)
540540
541 if self.theme.background_direction == u'horizontal':541 if self.theme.background_direction == u'horizontal':
542 self.GradientComboBox.setCurrentIndex(0)542 self.GradientComboBox.setCurrentIndex(0)
543 elif self.theme.background_direction == u'vertical':543 elif self.theme.background_direction == u'vertical':
544 self.GradientComboBox.setCurrentIndex(1)544 self.GradientComboBox.setCurrentIndex(1)
545 else:545 else:
546 self.GradientComboBox.setCurrentIndex(2)546 self.GradientComboBox.setCurrentIndex(2)
547547
548 self.FontMainSizeSpinBox.setValue(int(self.theme.font_main_proportion))548 self.FontMainSizeSpinBox.setValue(int(self.theme.font_main_proportion))
549 if not self.theme.font_main_italics and \549 if not self.theme.font_main_italics and \
550 self.theme.font_main_weight == u'Normal':550 self.theme.font_main_weight == u'Normal':
551 self.FontMainWeightComboBox.setCurrentIndex(0)551 self.FontMainWeightComboBox.setCurrentIndex(0)
552 elif not self.theme.font_main_italics and \552 elif not self.theme.font_main_italics and \
553 self.theme.font_main_weight == u'Bold':553 self.theme.font_main_weight == u'Bold':
554 self.FontMainWeightComboBox.setCurrentIndex(1)554 self.FontMainWeightComboBox.setCurrentIndex(1)
555 elif self.theme.font_main_italics and \555 elif self.theme.font_main_italics and \
556 self.theme.font_main_weight == u'Normal':556 self.theme.font_main_weight == u'Normal':
557 self.FontMainWeightComboBox.setCurrentIndex(2)557 self.FontMainWeightComboBox.setCurrentIndex(2)
558 else:558 else:
559 self.FontMainWeightComboBox.setCurrentIndex(3)559 self.FontMainWeightComboBox.setCurrentIndex(3)
560560
561 self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))561 self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
562 self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))562 self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
563 self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))563 self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
564 self.FontMainHeightSpinBox.setValue(int(self.theme.font_main_height))564 self.FontMainHeightSpinBox.setValue(int(self.theme.font_main_height))
565 self.FontFooterSizeSpinBox.setValue(565 self.FontFooterSizeSpinBox.setValue(
566 int(self.theme.font_footer_proportion))566 int(self.theme.font_footer_proportion))
567 if not self.theme.font_footer_italics and \567 if not self.theme.font_footer_italics and \
568 self.theme.font_footer_weight == u'Normal':568 self.theme.font_footer_weight == u'Normal':
569 self.FontFooterWeightComboBox.setCurrentIndex(0)569 self.FontFooterWeightComboBox.setCurrentIndex(0)
570 elif not self.theme.font_footer_italics and \570 elif not self.theme.font_footer_italics and \
571 self.theme.font_footer_weight == u'Bold':571 self.theme.font_footer_weight == u'Bold':
572 self.FontFooterWeightComboBox.setCurrentIndex(1)572 self.FontFooterWeightComboBox.setCurrentIndex(1)
573 elif self.theme.font_footer_italics and \573 elif self.theme.font_footer_italics and \
574 self.theme.font_footer_weight == u'Normal':574 self.theme.font_footer_weight == u'Normal':
575 self.FontFooterWeightComboBox.setCurrentIndex(2)575 self.FontFooterWeightComboBox.setCurrentIndex(2)
576 else:576 else:
577 self.FontFooterWeightComboBox.setCurrentIndex(3)577 self.FontFooterWeightComboBox.setCurrentIndex(3)
578 self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))578 self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
579 self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))579 self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
580 self.FontFooterWidthSpinBox.setValue(int(self.theme.font_footer_width))580 self.FontFooterWidthSpinBox.setValue(int(self.theme.font_footer_width))
581 self.FontFooterHeightSpinBox.setValue(581 self.FontFooterHeightSpinBox.setValue(
582 int(self.theme.font_footer_height))582 int(self.theme.font_footer_height))
583 self.FontMainColorPushButton.setStyleSheet(583 self.FontMainColorPushButton.setStyleSheet(
584 u'background-color: %s' % unicode(theme.font_main_color))584 u'background-color: %s' % unicode(theme.font_main_color))
585 self.FontFooterColorPushButton.setStyleSheet(585 self.FontFooterColorPushButton.setStyleSheet(
586 u'background-color: %s' % unicode(theme.font_footer_color))586 u'background-color: %s' % unicode(theme.font_footer_color))
587587
588 if self.theme.font_main_override == False:588 if self.theme.font_main_override == False:
589 self.FontMainDefaultCheckBox.setChecked(True)589 self.FontMainDefaultCheckBox.setChecked(True)
590 else:590 else:
591 self.FontMainDefaultCheckBox.setChecked(False)591 self.FontMainDefaultCheckBox.setChecked(False)
592592
593 if self.theme.font_footer_override == False:593 if self.theme.font_footer_override == False:
594 self.FontFooterDefaultCheckBox.setChecked(True)594 self.FontFooterDefaultCheckBox.setChecked(True)
595 else:595 else:
596 self.FontFooterDefaultCheckBox.setChecked(False)596 self.FontFooterDefaultCheckBox.setChecked(False)
597597
598 self.OutlineColorPushButton.setStyleSheet(598 self.OutlineColorPushButton.setStyleSheet(
599 u'background-color: %s' % unicode(theme.display_outline_color))599 u'background-color: %s' % unicode(theme.display_outline_color))
600 self.ShadowColorPushButton.setStyleSheet(600 self.ShadowColorPushButton.setStyleSheet(
601 u'background-color: %s' % unicode(theme.display_shadow_color))601 u'background-color: %s' % unicode(theme.display_shadow_color))
602602
603 if self.theme.display_outline:603 if self.theme.display_outline:
604 self.OutlineCheckBox.setChecked(True)604 self.OutlineCheckBox.setChecked(True)
605 self.OutlineColorPushButton.setEnabled(True)605 self.OutlineColorPushButton.setEnabled(True)
606 else:606 else:
607 self.OutlineCheckBox.setChecked(False)607 self.OutlineCheckBox.setChecked(False)
608 self.OutlineColorPushButton.setEnabled(False)608 self.OutlineColorPushButton.setEnabled(False)
609609
610 if self.theme.display_shadow:610 if self.theme.display_shadow:
611 self.ShadowCheckBox.setChecked(True)611 self.ShadowCheckBox.setChecked(True)
612 self.ShadowColorPushButton.setEnabled(True)612 self.ShadowColorPushButton.setEnabled(True)
613 else:613 else:
614 self.ShadowCheckBox.setChecked(False)614 self.ShadowCheckBox.setChecked(False)
615 self.ShadowColorPushButton.setEnabled(False)615 self.ShadowColorPushButton.setEnabled(False)
616616
617 self.HorizontalComboBox.setCurrentIndex(617 self.HorizontalComboBox.setCurrentIndex(
618 int(self.theme.display_horizontalAlign))618 int(self.theme.display_horizontalAlign))
619 self.VerticalComboBox.setCurrentIndex(619 self.VerticalComboBox.setCurrentIndex(
620 int(self.theme.display_verticalAlign))620 int(self.theme.display_verticalAlign))
621621
622 def stateChanging(self, theme):622 def stateChanging(self, theme):
623 if theme.background_mode == u'transparent':623 if theme.background_mode == u'transparent':
624 self.Color1Label.setVisible(False)624 self.Color1Label.setVisible(False)
625 self.Color1PushButton.setVisible(False)625 self.Color1PushButton.setVisible(False)
626 self.Color2Label.setVisible(False)626 self.Color2Label.setVisible(False)
627 self.Color2PushButton.setVisible(False)627 self.Color2PushButton.setVisible(False)
628 self.ImageLabel.setVisible(False)628 self.ImageLabel.setVisible(False)
629 self.ImageLineEdit.setVisible(False)629 self.ImageLineEdit.setVisible(False)
630 self.ImageFilenameWidget.setVisible(False)630 self.ImageFilenameWidget.setVisible(False)
631 self.GradientLabel.setVisible(False)631 self.GradientLabel.setVisible(False)
632 self.GradientComboBox.setVisible(False)632 self.GradientComboBox.setVisible(False)
633 self.BackgroundTypeComboBox.setVisible(False)633 self.BackgroundTypeComboBox.setVisible(False)
634 self.BackgroundTypeLabel.setVisible(False)634 self.BackgroundTypeLabel.setVisible(False)
635 else:635 else:
636 self.BackgroundTypeComboBox.setVisible(True)636 self.BackgroundTypeComboBox.setVisible(True)
637 self.BackgroundTypeLabel.setVisible(True)637 self.BackgroundTypeLabel.setVisible(True)
638 if theme.background_type == u'solid':638 if theme.background_type == u'solid':
639 self.Color1PushButton.setStyleSheet(639 self.Color1PushButton.setStyleSheet(
640 u'background-color: %s' % unicode(theme.background_color))640 u'background-color: %s' % unicode(theme.background_color))
641 self.Color1Label.setText(translate(u'ThemeManager',641 self.Color1Label.setText(translate(u'ThemeManager',
642 u'Background Color:'))642 u'Background Color:'))
643 self.Color1Label.setVisible(True)643 self.Color1Label.setVisible(True)
644 self.Color1PushButton.setVisible(True)644 self.Color1PushButton.setVisible(True)
645 self.Color2Label.setVisible(False)645 self.Color2Label.setVisible(False)
646 self.Color2PushButton.setVisible(False)646 self.Color2PushButton.setVisible(False)
647 self.ImageLabel.setVisible(False)647 self.ImageLabel.setVisible(False)
648 self.ImageLineEdit.setVisible(False)648 self.ImageLineEdit.setVisible(False)
649 self.ImageFilenameWidget.setVisible(False)649 self.ImageFilenameWidget.setVisible(False)
650 self.GradientLabel.setVisible(False)650 self.GradientLabel.setVisible(False)
651 self.GradientComboBox.setVisible(False)651 self.GradientComboBox.setVisible(False)
652 elif theme.background_type == u'gradient':652 elif theme.background_type == u'gradient':
653 self.Color1PushButton.setStyleSheet(u'background-color: %s' \653 self.Color1PushButton.setStyleSheet(u'background-color: %s' \
654 % unicode(theme.background_startColor))654 % unicode(theme.background_startColor))
655 self.Color2PushButton.setStyleSheet(u'background-color: %s' \655 self.Color2PushButton.setStyleSheet(u'background-color: %s' \
656 % unicode(theme.background_endColor))656 % unicode(theme.background_endColor))
657 self.Color1Label.setText(translate(u'ThemeManager',657 self.Color1Label.setText(translate(u'ThemeManager',
658 u'First Color:'))658 u'First Color:'))
659 self.Color2Label.setText(translate(u'ThemeManager',659 self.Color2Label.setText(translate(u'ThemeManager',
660 u'Second Color:'))660 u'Second Color:'))
661 self.Color1Label.setVisible(True)661 self.Color1Label.setVisible(True)
662 self.Color1PushButton.setVisible(True)662 self.Color1PushButton.setVisible(True)
663 self.Color2Label.setVisible(True)663 self.Color2Label.setVisible(True)
664 self.Color2PushButton.setVisible(True)664 self.Color2PushButton.setVisible(True)
665 self.ImageLabel.setVisible(False)665 self.ImageLabel.setVisible(False)
666 self.ImageLineEdit.setVisible(False)666 self.ImageLineEdit.setVisible(False)
667 self.ImageFilenameWidget.setVisible(False)667 self.ImageFilenameWidget.setVisible(False)
668 self.GradientLabel.setVisible(True)668 self.GradientLabel.setVisible(True)
669 self.GradientComboBox.setVisible(True)669 self.GradientComboBox.setVisible(True)
670 else: # must be image670 else: # must be image
671 self.Color1Label.setVisible(False)671 self.Color1Label.setVisible(False)
672 self.Color1PushButton.setVisible(False)672 self.Color1PushButton.setVisible(False)
673 self.Color2Label.setVisible(False)673 self.Color2Label.setVisible(False)
674 self.Color2PushButton.setVisible(False)674 self.Color2PushButton.setVisible(False)
675 self.ImageLabel.setVisible(True)675 self.ImageLabel.setVisible(True)
676 self.ImageLineEdit.setVisible(True)676 self.ImageLineEdit.setVisible(True)
677 self.ImageFilenameWidget.setVisible(True)677 self.ImageFilenameWidget.setVisible(True)
678 self.GradientLabel.setVisible(False)678 self.GradientLabel.setVisible(False)
679 self.GradientComboBox.setVisible(False)679 self.GradientComboBox.setVisible(False)
680680
681 if theme.font_main_override == False:681 if theme.font_main_override == False:
682 self.FontMainXSpinBox.setEnabled(False)682 self.FontMainXSpinBox.setEnabled(False)
683 self.FontMainYSpinBox.setEnabled(False)683 self.FontMainYSpinBox.setEnabled(False)
684 self.FontMainWidthSpinBox.setEnabled(False)684 self.FontMainWidthSpinBox.setEnabled(False)
685 self.FontMainHeightSpinBox.setEnabled(False)685 self.FontMainHeightSpinBox.setEnabled(False)
686 else:686 else:
687 self.FontMainXSpinBox.setEnabled(True)687 self.FontMainXSpinBox.setEnabled(True)
688 self.FontMainYSpinBox.setEnabled(True)688 self.FontMainYSpinBox.setEnabled(True)
689 self.FontMainWidthSpinBox.setEnabled(True)689 self.FontMainWidthSpinBox.setEnabled(True)
690 self.FontMainHeightSpinBox.setEnabled(True)690 self.FontMainHeightSpinBox.setEnabled(True)
691691
692 if theme.font_footer_override == False:692 if theme.font_footer_override == False:
693 self.FontFooterXSpinBox.setEnabled(False)693 self.FontFooterXSpinBox.setEnabled(False)
694 self.FontFooterYSpinBox.setEnabled(False)694 self.FontFooterYSpinBox.setEnabled(False)
695 self.FontFooterWidthSpinBox.setEnabled(False)695 self.FontFooterWidthSpinBox.setEnabled(False)
696 self.FontFooterHeightSpinBox.setEnabled(False)696 self.FontFooterHeightSpinBox.setEnabled(False)
697 else:697 else:
698 self.FontFooterXSpinBox.setEnabled(True)698 self.FontFooterXSpinBox.setEnabled(True)
699 self.FontFooterYSpinBox.setEnabled(True)699 self.FontFooterYSpinBox.setEnabled(True)
700 self.FontFooterWidthSpinBox.setEnabled(True)700 self.FontFooterWidthSpinBox.setEnabled(True)
701 self.FontFooterHeightSpinBox.setEnabled(True)701 self.FontFooterHeightSpinBox.setEnabled(True)
702702
703 if self.theme.display_outline:703 if self.theme.display_outline:
704 self.OutlineColorPushButton.setEnabled(True)704 self.OutlineColorPushButton.setEnabled(True)
705 else:705 else:
706 self.OutlineColorPushButton.setEnabled(False)706 self.OutlineColorPushButton.setEnabled(False)
707707
708 if self.theme.display_shadow:708 if self.theme.display_shadow:
709 self.ShadowColorPushButton.setEnabled(True)709 self.ShadowColorPushButton.setEnabled(True)
710 else:710 else:
711 self.ShadowColorPushButton.setEnabled(False)711 self.ShadowColorPushButton.setEnabled(False)
712712
713 def previewTheme(self, theme):713 def previewTheme(self, theme):
714 if self.allowPreview:714 if self.allowPreview:
715 frame = self.thememanager.generateImage(theme)715 frame = self.thememanager.generateImage(theme)
716 self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))716 self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
717717
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2009-09-13 14:12:38 +0000
+++ openlp/core/ui/thememanager.py 2009-09-13 15:14:45 +0000
@@ -1,462 +1,462 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=42# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
33
4###############################################################################4###############################################################################
5# OpenLP - Open Source Lyrics Projection #5# OpenLP - Open Source Lyrics Projection #
6# --------------------------------------------------------------------------- #6# --------------------------------------------------------------------------- #
7# Copyright (c) 2008-2009 Raoul Snyman #7# Copyright (c) 2008-2009 Raoul Snyman #
8# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #8# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
9# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #9# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
10# --------------------------------------------------------------------------- #10# --------------------------------------------------------------------------- #
11# This program is free software; you can redistribute it and/or modify it #11# This program is free software; you can redistribute it and/or modify it #
12# under the terms of the GNU General Public License as published by the Free #12# under the terms of the GNU General Public License as published by the Free #
13# Software Foundation; version 2 of the License. #13# Software Foundation; version 2 of the License. #
14# #14# #
15# This program is distributed in the hope that it will be useful, but WITHOUT #15# This program is distributed in the hope that it will be useful, but WITHOUT #
16# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #16# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
17# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #17# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
18# more details. #18# more details. #
19# #19# #
20# You should have received a copy of the GNU General Public License along #20# You should have received a copy of the GNU General Public License along #
21# with this program; if not, write to the Free Software Foundation, Inc., 59 #21# with this program; if not, write to the Free Software Foundation, Inc., 59 #
22# Temple Place, Suite 330, Boston, MA 02111-1307 USA #22# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
23###############################################################################23###############################################################################
2424
25import os25import os
26import sys26import sys
27import zipfile27import zipfile
28import shutil28import shutil
29import logging29import logging
3030
31from xml.etree.ElementTree import ElementTree, XML31from xml.etree.ElementTree import ElementTree, XML
32from PyQt4 import QtCore, QtGui32from PyQt4 import QtCore, QtGui
3333
34from openlp.core.ui import AmendThemeForm, ServiceManager34from openlp.core.ui import AmendThemeForm, ServiceManager
35from openlp.core.theme import Theme35from openlp.core.theme import Theme
36from openlp.core.lib import PluginConfig, OpenLPToolbar, ThemeXML, Renderer, \36from openlp.core.lib import PluginConfig, OpenLPToolbar, ThemeXML, Renderer, \
37 translate, str_to_bool, file_to_xml, buildIcon, Receiver37 translate, str_to_bool, file_to_xml, buildIcon, Receiver
38from openlp.core.utils import ConfigHelper38from openlp.core.utils import ConfigHelper
3939
40class ThemeManager(QtGui.QWidget):40class ThemeManager(QtGui.QWidget):
41 """41 """
42 Manages the orders of Theme.42 Manages the orders of Theme.
43 """43 """
44 global log44 global log
45 log = logging.getLogger(u'ThemeManager')45 log = logging.getLogger(u'ThemeManager')
4646
47 def __init__(self, parent):47 def __init__(self, parent):
48 QtGui.QWidget.__init__(self, parent)48 QtGui.QWidget.__init__(self, parent)
49 self.parent = parent49 self.parent = parent
50 self.Layout = QtGui.QVBoxLayout(self)50 self.Layout = QtGui.QVBoxLayout(self)
51 self.Layout.setSpacing(0)51 self.Layout.setSpacing(0)
52 self.Layout.setMargin(0)52 self.Layout.setMargin(0)
53 self.amendThemeForm = AmendThemeForm(self)53 self.amendThemeForm = AmendThemeForm(self)
54 self.Toolbar = OpenLPToolbar(self)54 self.Toolbar = OpenLPToolbar(self)
55 self.Toolbar.addToolbarButton(55 self.Toolbar.addToolbarButton(
56 translate(u'ThemeManager', u'New Theme'), u':/themes/theme_new.png',56 translate(u'ThemeManager', u'New Theme'), u':/themes/theme_new.png',
57 translate(u'ThemeManager', u'Create a new theme'), self.onAddTheme)57 translate(u'ThemeManager', u'Create a new theme'), self.onAddTheme)
58 self.Toolbar.addToolbarButton(58 self.Toolbar.addToolbarButton(
59 translate(u'ThemeManager', u'Edit Theme'),59 translate(u'ThemeManager', u'Edit Theme'),
60 u':/themes/theme_edit.png',60 u':/themes/theme_edit.png',
61 translate(u'ThemeManager', u'Edit a theme'), self.onEditTheme)61 translate(u'ThemeManager', u'Edit a theme'), self.onEditTheme)
62 self.Toolbar.addToolbarButton(62 self.Toolbar.addToolbarButton(
63 translate(u'ThemeManager', u'Delete Theme'),63 translate(u'ThemeManager', u'Delete Theme'),
64 u':/themes/theme_delete.png',64 u':/themes/theme_delete.png',
65 translate(u'ThemeManager', u'Delete a theme'), self.onDeleteTheme)65 translate(u'ThemeManager', u'Delete a theme'), self.onDeleteTheme)
66 self.Toolbar.addSeparator()66 self.Toolbar.addSeparator()
67 self.Toolbar.addToolbarButton(67 self.Toolbar.addToolbarButton(
68 translate(u'ThemeManager', u'Import Theme'),68 translate(u'ThemeManager', u'Import Theme'),
69 u':/themes/theme_import.png',69 u':/themes/theme_import.png',
70 translate(u'ThemeManager', u'Import a theme'), self.onImportTheme)70 translate(u'ThemeManager', u'Import a theme'), self.onImportTheme)
71 self.Toolbar.addToolbarButton(71 self.Toolbar.addToolbarButton(
72 translate(u'ThemeManager', u'Export Theme'),72 translate(u'ThemeManager', u'Export Theme'),
73 u':/themes/theme_export.png',73 u':/themes/theme_export.png',
74 translate(u'ThemeManager', u'Export a theme'), self.onExportTheme)74 translate(u'ThemeManager', u'Export a theme'), self.onExportTheme)
75 self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)75 self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
76 self.Layout.addWidget(self.Toolbar)76 self.Layout.addWidget(self.Toolbar)
77 self.ThemeListWidget = QtGui.QListWidget(self)77 self.ThemeListWidget = QtGui.QListWidget(self)
78 self.ThemeListWidget.setAlternatingRowColors(True)78 self.ThemeListWidget.setAlternatingRowColors(True)
79 self.ThemeListWidget.setIconSize(QtCore.QSize(88,50))79 self.ThemeListWidget.setIconSize(QtCore.QSize(88,50))
80 self.Layout.addWidget(self.ThemeListWidget)80 self.Layout.addWidget(self.ThemeListWidget)
81 #Signals81 #Signals
82 QtCore.QObject.connect(self.ThemeListWidget,82 QtCore.QObject.connect(self.ThemeListWidget,
83 QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),83 QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
84 self.changeGlobalFromScreen)84 self.changeGlobalFromScreen)
85 QtCore.QObject.connect(Receiver.get_receiver(),85 QtCore.QObject.connect(Receiver.get_receiver(),
86 QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab)86 QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab)
87 #Variables87 #Variables
88 self.themelist = []88 self.themelist = []
89 self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')89 self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
90 self.checkThemesExists(self.path)90 self.checkThemesExists(self.path)
91 self.amendThemeForm.path = self.path91 self.amendThemeForm.path = self.path
92 # Last little bits of setting up92 # Last little bits of setting up
93 self.config = PluginConfig(u'themes')93 self.config = PluginConfig(u'themes')
94 self.servicePath = self.config.get_data_path()94 self.servicePath = self.config.get_data_path()
95 self.global_theme = unicode(95 self.global_theme = unicode(
96 self.config.get_config(u'theme global theme', u''))96 self.config.get_config(u'theme global theme', u''))
9797
98 def changeGlobalFromTab(self, themeName):98 def changeGlobalFromTab(self, themeName):
99 log.debug(u'changeGlobalFromTab %s', themeName)99 log.debug(u'changeGlobalFromTab %s', themeName)
100 for count in range (0, self.ThemeListWidget.count()):100 for count in range (0, self.ThemeListWidget.count()):
101 #reset the old name101 #reset the old name
102 item = self.ThemeListWidget.item(count)102 item = self.ThemeListWidget.item(count)
103 oldName = item.text()103 oldName = item.text()
104 newName = unicode(item.data(QtCore.Qt.UserRole).toString())104 newName = unicode(item.data(QtCore.Qt.UserRole).toString())
105 if oldName != newName:105 if oldName != newName:
106 self.ThemeListWidget.item(count).setText(newName)106 self.ThemeListWidget.item(count).setText(newName)
107 #Set the new name107 #Set the new name
108 if themeName == newName:108 if themeName == newName:
109 name = u'%s (%s)' % (newName, translate(u'ThemeManager',109 name = u'%s (%s)' % (newName, translate(u'ThemeManager',
110 u'default'))110 u'default'))
111 self.ThemeListWidget.item(count).setText(name)111 self.ThemeListWidget.item(count).setText(name)
112112
113 def changeGlobalFromScreen(self, index):113 def changeGlobalFromScreen(self, index):
114 log.debug(u'changeGlobalFromScreen %s', index)114 log.debug(u'changeGlobalFromScreen %s', index)
115 for count in range (0, self.ThemeListWidget.count()):115 for count in range (0, self.ThemeListWidget.count()):
116 item = self.ThemeListWidget.item(count)116 item = self.ThemeListWidget.item(count)
117 oldName = item.text()117 oldName = item.text()
118 #reset the old name118 #reset the old name
119 if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):119 if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):
120 self.ThemeListWidget.item(count).setText(120 self.ThemeListWidget.item(count).setText(
121 unicode(item.data(QtCore.Qt.UserRole).toString()))121 unicode(item.data(QtCore.Qt.UserRole).toString()))
122 #Set the new name122 #Set the new name
123 if count == index.row():123 if count == index.row():
124 self.global_theme = unicode(124 self.global_theme = unicode(
125 self.ThemeListWidget.item(count).text())125 self.ThemeListWidget.item(count).text())
126 name = u'%s (%s)' % (self.global_theme,126 name = u'%s (%s)' % (self.global_theme,
127 translate(u'ThemeManager', u'default'))127 translate(u'ThemeManager', u'default'))
128 self.ThemeListWidget.item(count).setText(name)128 self.ThemeListWidget.item(count).setText(name)
129 self.config.set_config(u'theme global theme', self.global_theme)129 self.config.set_config(u'theme global theme', self.global_theme)
130 Receiver().send_message(u'update_global_theme',130 Receiver().send_message(u'update_global_theme',
131 self.global_theme)131 self.global_theme)
132 self.pushThemes()132 self.pushThemes()
133133
134 def onAddTheme(self):134 def onAddTheme(self):
135 self.amendThemeForm.theme.parse(self.baseTheme())135 self.amendThemeForm.theme.parse(self.baseTheme())
136 self.amendThemeForm.loadTheme(None)136 self.amendThemeForm.loadTheme(None)
137 self.amendThemeForm.exec_()137 self.amendThemeForm.exec_()
138138
139 def onEditTheme(self):139 def onEditTheme(self):
140 item = self.ThemeListWidget.currentItem()140 item = self.ThemeListWidget.currentItem()
141 if item is not None:141 if item is not None:
142 self.amendThemeForm.loadTheme(142 self.amendThemeForm.loadTheme(
143 unicode(item.data(QtCore.Qt.UserRole).toString()))143 unicode(item.data(QtCore.Qt.UserRole).toString()))
144 self.amendThemeForm.exec_()144 self.amendThemeForm.exec_()
145145
146 def onDeleteTheme(self):146 def onDeleteTheme(self):
147 self.global_theme = unicode(147 self.global_theme = unicode(
148 self.config.get_config(u'theme global theme', u''))148 self.config.get_config(u'theme global theme', u''))
149 item = self.ThemeListWidget.currentItem()149 item = self.ThemeListWidget.currentItem()
150 if item is not None:150 if item is not None:
151 theme = unicode(item.text())151 theme = unicode(item.text())
152 # should be the same unless default152 # should be the same unless default
153 if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):153 if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
154 QtGui.QMessageBox.critical(self,154 QtGui.QMessageBox.critical(self,
155 translate(u'ThemeManager', u'Error'),155 translate(u'ThemeManager', u'Error'),
156 translate(u'ThemeManager',156 translate(u'ThemeManager',
157 u'You are unable to delete the default theme!'),157 u'You are unable to delete the default theme!'),
158 QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))158 QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
159 else:159 else:
160 self.themelist.remove(theme)160 self.themelist.remove(theme)
161 th = theme + u'.png'161 th = theme + u'.png'
162 row = self.ThemeListWidget.row(item)162 row = self.ThemeListWidget.row(item)
163 self.ThemeListWidget.takeItem(row)163 self.ThemeListWidget.takeItem(row)
164 try:164 try:
165 os.remove(os.path.join(self.path, th))165 os.remove(os.path.join(self.path, th))
166 except:166 except:
167 #if not present do not worry167 #if not present do not worry
168 pass168 pass
169 try:169 try:
170 shutil.rmtree(os.path.join(self.path, theme))170 shutil.rmtree(os.path.join(self.path, theme))
171 except:171 except:
172 #if not present do not worry172 #if not present do not worry
173 pass173 pass
174 # As we do not reload the themes push out the change174 # As we do not reload the themes push out the change
175 # Reaload the list as the internal lists and events need175 # Reaload the list as the internal lists and events need
176 # to be triggered176 # to be triggered
177 self.pushThemes()177 self.pushThemes()
178178
179 def onExportTheme(self):179 def onExportTheme(self):
180 pass180 pass
181181
182 def onImportTheme(self):182 def onImportTheme(self):
183 files = QtGui.QFileDialog.getOpenFileNames(None,183 files = QtGui.QFileDialog.getOpenFileNames(None,
184 translate(u'ThemeManager', u'Select Theme Import File'),184 translate(u'ThemeManager', u'Select Theme Import File'),
185 self.path, u'Theme (*.*)')185 self.path, u'Theme (*.*)')
186 log.info(u'New Themes %s', unicode(files))186 log.info(u'New Themes %s', unicode(files))
187 if len(files) > 0:187 if len(files) > 0:
188 for file in files:188 for file in files:
189 self.unzipTheme(file, self.path)189 self.unzipTheme(file, self.path)
190 self.loadThemes()190 self.loadThemes()
191191
192 def loadThemes(self):192 def loadThemes(self):
193 """193 """
194 Loads the theme lists and triggers updates accross194 Loads the theme lists and triggers updates accross
195 the whole system using direct calls or core functions195 the whole system using direct calls or core functions
196 and events for the plugins.196 and events for the plugins.
197 The plugins will call back in to get the real list if they want it.197 The plugins will call back in to get the real list if they want it.
198 """198 """
199 log.debug(u'Load themes from dir')199 log.debug(u'Load themes from dir')
200 self.themelist = []200 self.themelist = []
201 self.ThemeListWidget.clear()201 self.ThemeListWidget.clear()
202 for root, dirs, files in os.walk(self.path):202 for root, dirs, files in os.walk(self.path):
203 for name in files:203 for name in files:
204 if name.endswith(u'.png'):204 if name.endswith(u'.png'):
205 #check to see file is in theme root directory205 #check to see file is in theme root directory
206 theme = os.path.join(self.path, name)206 theme = os.path.join(self.path, name)
207 if os.path.exists(theme):207 if os.path.exists(theme):
208 (path, filename) = os.path.split(unicode(file))208 (path, filename) = os.path.split(unicode(file))
209 textName = os.path.splitext(name)[0]209 textName = os.path.splitext(name)[0]
210 if textName == self.global_theme:210 if textName == self.global_theme:
211 name = u'%s (%s)' % (textName,211 name = u'%s (%s)' % (textName,
212 translate(u'ThemeManager', u'default'))212 translate(u'ThemeManager', u'default'))
213 else:213 else:
214 name = textName214 name = textName
215 item_name = QtGui.QListWidgetItem(name)215 item_name = QtGui.QListWidgetItem(name)
216 item_name.setIcon(buildIcon(theme))216 item_name.setIcon(buildIcon(theme))
217 item_name.setData(QtCore.Qt.UserRole,217 item_name.setData(QtCore.Qt.UserRole,
218 QtCore.QVariant(textName))218 QtCore.QVariant(textName))
219 self.ThemeListWidget.addItem(item_name)219 self.ThemeListWidget.addItem(item_name)
220 self.themelist.append(textName)220 self.themelist.append(textName)
221 self.pushThemes()221 self.pushThemes()
222222
223 def pushThemes(self):223 def pushThemes(self):
224 Receiver().send_message(u'update_themes', self.getThemes() )224 Receiver().send_message(u'update_themes', self.getThemes() )
225225
226 def getThemes(self):226 def getThemes(self):
227 return self.themelist227 return self.themelist
228228
229 def getThemeData(self, themename):229 def getThemeData(self, themename):
230 log.debug(u'getthemedata for theme %s', themename)230 log.debug(u'getthemedata for theme %s', themename)
231 xml_file = os.path.join(self.path, unicode(themename),231 xml_file = os.path.join(self.path, unicode(themename),
232 unicode(themename) + u'.xml')232 unicode(themename) + u'.xml')
233 try:233 try:
234 xml = file_to_xml(xml_file)234 xml = file_to_xml(xml_file)
235 except:235 except:
236 newtheme = ThemeXML()236 newtheme = ThemeXML()
237 newtheme.new_document(u'New Theme')237 newtheme.new_document(u'New Theme')
238 newtheme.add_background_solid(unicode(u'#000000'))238 newtheme.add_background_solid(unicode(u'#000000'))
239 newtheme.add_font(unicode(QtGui.QFont().family()),239 newtheme.add_font(unicode(QtGui.QFont().family()),
240 unicode(u'#FFFFFF'), unicode(30), u'False')240 unicode(u'#FFFFFF'), unicode(30), u'False')
241 newtheme.add_font(unicode(QtGui.QFont().family()),241 newtheme.add_font(unicode(QtGui.QFont().family()),
242 unicode(u'#FFFFFF'), unicode(12), u'False', u'footer')242 unicode(u'#FFFFFF'), unicode(12), u'False', u'footer')
243 newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',243 newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
244 unicode(u'#FFFFFF'), unicode(0), unicode(0), unicode(0))244 unicode(u'#FFFFFF'), unicode(0), unicode(0), unicode(0))
245 xml = newtheme.extract_xml()245 xml = newtheme.extract_xml()
246 theme = ThemeXML()246 theme = ThemeXML()
247 theme.parse(xml)247 theme.parse(xml)
248 theme.extend_image_filename(self.path)248 theme.extend_image_filename(self.path)
249 self.cleanTheme(theme)249 self.cleanTheme(theme)
250 return theme250 return theme
251251
252 def checkThemesExists(self, dir):252 def checkThemesExists(self, dir):
253 log.debug(u'check themes')253 log.debug(u'check themes')
254 if os.path.exists(dir) == False:254 if os.path.exists(dir) == False:
255 os.mkdir(dir)255 os.mkdir(dir)
256256
257 def unzipTheme(self, filename, dir):257 def unzipTheme(self, filename, dir):
258 """258 """
259 Unzip the theme, remove the preview file if stored259 Unzip the theme, remove the preview file if stored
260 Generate a new preview fileCheck the XML theme version and upgrade if260 Generate a new preview fileCheck the XML theme version and upgrade if
261 necessary.261 necessary.
262 """262 """
263 log.debug(u'Unzipping theme %s', filename)263 log.debug(u'Unzipping theme %s', filename)
264 zip = zipfile.ZipFile(unicode(filename))264 zip = zipfile.ZipFile(unicode(filename))
265 filexml = None265 filexml = None
266 themename = None266 themename = None
267 for file in zip.namelist():267 for file in zip.namelist():
268 if file.endswith(os.path.sep):268 if file.endswith(os.path.sep):
269 theme_dir = os.path.join(dir, file)269 theme_dir = os.path.join(dir, file)
270 if os.path.exists(theme_dir) == False:270 if os.path.exists(theme_dir) == False:
271 os.mkdir(os.path.join(dir, file))271 os.mkdir(os.path.join(dir, file))
272 else:272 else:
273 fullpath = os.path.join(dir, file)273 fullpath = os.path.join(dir, file)
274 names = file.split(os.path.sep)274 names = file.split(os.path.sep)
275 if len(names) > 1:275 if len(names) > 1:
276 # not preview file276 # not preview file
277 if themename is None:277 if themename is None:
278 themename = names[0]278 themename = names[0]
279 xml_data = zip.read(file)279 xml_data = zip.read(file)
280 if os.path.splitext(file)[1].lower() in [u'.xml']:280 if os.path.splitext(file)[1].lower() in [u'.xml']:
281 if self.checkVersion1(xml_data):281 if self.checkVersion1(xml_data):
282 # upgrade theme xml282 # upgrade theme xml
283 filexml = self.migrateVersion122(filename,283 filexml = self.migrateVersion122(filename,
284 fullpath, xml_data)284 fullpath, xml_data)
285 else:285 else:
286 filexml = xml_data286 filexml = xml_data
287 outfile = open(fullpath, u'w')287 outfile = open(fullpath, u'w')
288 outfile.write(filexml)288 outfile.write(filexml)
289 outfile.close()289 outfile.close()
290 else:290 else:
291 outfile = open(fullpath, u'w')291 outfile = open(fullpath, u'w')
292 outfile.write(zip.read(file))292 outfile.write(zip.read(file))
293 outfile.close()293 outfile.close()
294 self.generateAndSaveImage(dir, themename, filexml)294 self.generateAndSaveImage(dir, themename, filexml)
295295
296 def checkVersion1(self, xmlfile):296 def checkVersion1(self, xmlfile):
297 """297 """
298 Am I a version 1 theme298 Am I a version 1 theme
299 """299 """
300 log.debug(u'checkVersion1 ')300 log.debug(u'checkVersion1 ')
301 theme = xmlfile301 theme = xmlfile
302 tree = ElementTree(element=XML(theme)).getroot()302 tree = ElementTree(element=XML(theme)).getroot()
303 if tree.find(u'BackgroundType') is None:303 if tree.find(u'BackgroundType') is None:
304 return False304 return False
305 else:305 else:
306 return True306 return True
307307
308 def migrateVersion122(self, filename, fullpath, xml_data):308 def migrateVersion122(self, filename, fullpath, xml_data):
309 """309 """
310 Called by convert the xml data from version 1 format310 Called by convert the xml data from version 1 format
311 to the current format.311 to the current format.
312 New fields are defaulted but the new theme is useable312 New fields are defaulted but the new theme is useable
313 """313 """
314 log.debug(u'migrateVersion122 %s %s', filename, fullpath)314 log.debug(u'migrateVersion122 %s %s', filename, fullpath)
315 theme = Theme(xml_data)315 theme = Theme(xml_data)
316 newtheme = ThemeXML()316 newtheme = ThemeXML()
317 newtheme.new_document(theme.Name)317 newtheme.new_document(theme.Name)
318 if theme.BackgroundType == 0:318 if theme.BackgroundType == 0:
319 newtheme.add_background_solid(unicode(319 newtheme.add_background_solid(unicode(
320 theme.BackgroundParameter1.name()))320 theme.BackgroundParameter1.name()))
321 elif theme.BackgroundType == 1:321 elif theme.BackgroundType == 1:
322 direction = u'vertical'322 direction = u'vertical'
323 if theme.BackgroundParameter3.name() == 1:323 if theme.BackgroundParameter3.name() == 1:
324 direction = u'horizontal'324 direction = u'horizontal'
325 newtheme.add_background_gradient(325 newtheme.add_background_gradient(
326 unicode(theme.BackgroundParameter1.name()),326 unicode(theme.BackgroundParameter1.name()),
327 unicode(theme.BackgroundParameter2.name()), direction)327 unicode(theme.BackgroundParameter2.name()), direction)
328 else:328 else:
329 newtheme.add_background_image(unicode(theme.BackgroundParameter1))329 newtheme.add_background_image(unicode(theme.BackgroundParameter1))
330330
331 newtheme.add_font(unicode(theme.FontName),331 newtheme.add_font(unicode(theme.FontName),
332 unicode(theme.FontColor.name()),332 unicode(theme.FontColor.name()),
333 unicode(theme.FontProportion * 2), u'False')333 unicode(theme.FontProportion * 2), u'False')
334 newtheme.add_font(unicode(theme.FontName),334 newtheme.add_font(unicode(theme.FontName),
335 unicode(theme.FontColor.name()),335 unicode(theme.FontColor.name()),
336 unicode(12), u'False', u'footer')336 unicode(12), u'False', u'footer')
337 outline = False337 outline = False
338 shadow = False338 shadow = False
339 if theme.Shadow == 1:339 if theme.Shadow == 1:
340 shadow = True340 shadow = True
341 if theme.Outline == 1:341 if theme.Outline == 1:
342 outline = True342 outline = True
343 newtheme.add_display(unicode(shadow), unicode(theme.ShadowColor.name()),343 newtheme.add_display(unicode(shadow), unicode(theme.ShadowColor.name()),
344 unicode(outline), unicode(theme.OutlineColor.name()),344 unicode(outline), unicode(theme.OutlineColor.name()),
345 unicode(theme.HorizontalAlign), unicode(theme.VerticalAlign),345 unicode(theme.HorizontalAlign), unicode(theme.VerticalAlign),
346 unicode(theme.WrapStyle))346 unicode(theme.WrapStyle))
347 return newtheme.extract_xml()347 return newtheme.extract_xml()
348348
349 def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from,349 def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from,
350 image_to) :350 image_to) :
351 """351 """
352 Called by thememaintenance Dialog to save the theme352 Called by thememaintenance Dialog to save the theme
353 and to trigger the reload of the theme list353 and to trigger the reload of the theme list
354 """354 """
355 log.debug(u'saveTheme %s %s', name, theme_xml)355 log.debug(u'saveTheme %s %s', name, theme_xml)
356 theme_dir = os.path.join(self.path, name)356 theme_dir = os.path.join(self.path, name)
357 if os.path.exists(theme_dir) == False:357 if os.path.exists(theme_dir) == False:
358 os.mkdir(os.path.join(self.path, name))358 os.mkdir(os.path.join(self.path, name))
359 theme_file = os.path.join(theme_dir, name + u'.xml')359 theme_file = os.path.join(theme_dir, name + u'.xml')
360 log.debug(theme_file)360 log.debug(theme_file)
361361
362 result = QtGui.QMessageBox.Yes362 result = QtGui.QMessageBox.Yes
363 if os.path.exists(theme_file):363 if os.path.exists(theme_file):
364 result = QtGui.QMessageBox.question(364 result = QtGui.QMessageBox.question(
365 self,365 self,
366 translate(u'ThemeManager', u'Theme Exists'),366 translate(u'ThemeManager', u'Theme Exists'),
367 translate(u'ThemeManager', u'A theme with this name already exists, would you like to overwrite it?'),367 translate(u'ThemeManager', u'A theme with this name already exists, would you like to overwrite it?'),
368 (QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),368 (QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
369 QtGui.QMessageBox.No)369 QtGui.QMessageBox.No)
370 if result == QtGui.QMessageBox.Yes:370 if result == QtGui.QMessageBox.Yes:
371 # Save the theme, overwriting the existing theme if necessary.371 # Save the theme, overwriting the existing theme if necessary.
372 outfile = open(theme_file, u'w')372 outfile = open(theme_file, u'w')
373 outfile.write(theme_pretty_xml)373 outfile.write(theme_pretty_xml)
374 outfile.close()374 outfile.close()
375 if image_from is not None and image_from != image_to:375 if image_from is not None and image_from != image_to:
376 shutil.copyfile(image_from, image_to)376 shutil.copyfile(image_from, image_to)
377377
378 self.generateAndSaveImage(self.path, name, theme_xml)378 self.generateAndSaveImage(self.path, name, theme_xml)
379 self.loadThemes()379 self.loadThemes()
380 else:380 else:
381 # Don't close the dialog - allow the user to change the name of381 # Don't close the dialog - allow the user to change the name of
382 # the theme or to cancel the theme dialog completely.382 # the theme or to cancel the theme dialog completely.
383 return False383 return False
384384
385 def generateAndSaveImage(self, dir, name, theme_xml):385 def generateAndSaveImage(self, dir, name, theme_xml):
386 log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml)386 log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml)
387 theme = ThemeXML()387 theme = ThemeXML()
388 theme.parse(theme_xml)388 theme.parse(theme_xml)
389 theme.extend_image_filename(dir)389 theme.extend_image_filename(dir)
390 frame = self.generateImage(theme)390 frame = self.generateImage(theme)
391 samplepathname = os.path.join(self.path, name + u'.png')391 samplepathname = os.path.join(self.path, name + u'.png')
392 if os.path.exists(samplepathname):392 if os.path.exists(samplepathname):
393 os.unlink(samplepathname)393 os.unlink(samplepathname)
394 frame.save(samplepathname, u'png')394 frame.save(samplepathname, u'png')
395 log.debug(u'Theme image written to %s', samplepathname)395 log.debug(u'Theme image written to %s', samplepathname)
396396
397 def generateImage(self, themedata):397 def generateImage(self, themedata):
398 """398 """
399 Call the RenderManager to build a Sample Image399 Call the RenderManager to build a Sample Image
400 """400 """
401 log.debug(u'generateImage %s ', themedata)401 log.debug(u'generateImage %s ', themedata)
402 frame = self.parent.RenderManager.generate_preview(themedata)402 frame = self.parent.RenderManager.generate_preview(themedata)
403 return frame403 return frame
404404
405 def getPreviewImage(self, theme):405 def getPreviewImage(self, theme):
406 log.debug(u'getPreviewImage %s ', theme)406 log.debug(u'getPreviewImage %s ', theme)
407 image = os.path.join(self.path, theme + u'.png')407 image = os.path.join(self.path, theme + u'.png')
408 return image408 return image
409409
410 def baseTheme(self):410 def baseTheme(self):
411 log.debug(u'base theme created')411 log.debug(u'base theme created')
412 newtheme = ThemeXML()412 newtheme = ThemeXML()
413 newtheme.new_document(u'New Theme')413 newtheme.new_document(u'New Theme')
414 newtheme.add_background_solid(unicode(u'#000000'))414 newtheme.add_background_solid(unicode(u'#000000'))
415 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),415 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
416 unicode(30), u'False')416 unicode(30), u'False')
417 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),417 newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
418 unicode(12), u'False', u'footer')418 unicode(12), u'False', u'footer')
419 newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',419 newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
420 unicode(u'#FFFFFF'), unicode(0), unicode(0), unicode(0))420 unicode(u'#FFFFFF'), unicode(0), unicode(0), unicode(0))
421 return newtheme.extract_xml()421 return newtheme.extract_xml()
422422
423 def cleanTheme(self, theme):423 def cleanTheme(self, theme):
424 theme.background_color = theme.background_color.strip()424 theme.background_color = theme.background_color.strip()
425 theme.background_direction = theme.background_direction.strip()425 theme.background_direction = theme.background_direction.strip()
426 theme.background_endColor = theme.background_endColor.strip()426 theme.background_endColor = theme.background_endColor.strip()
427 if theme.background_filename:427 if theme.background_filename:
428 theme.background_filename = theme.background_filename.strip()428 theme.background_filename = theme.background_filename.strip()
429 #theme.background_mode429 #theme.background_mode
430 theme.background_startColor = theme.background_startColor.strip()430 theme.background_startColor = theme.background_startColor.strip()
431 #theme.background_type431 #theme.background_type
432 if theme.display_display:432 if theme.display_display:
433 theme.display_display = theme.display_display.strip()433 theme.display_display = theme.display_display.strip()
434 theme.display_horizontalAlign = theme.display_horizontalAlign.strip()434 theme.display_horizontalAlign = theme.display_horizontalAlign.strip()
435 theme.display_outline = str_to_bool(theme.display_outline)435 theme.display_outline = str_to_bool(theme.display_outline)
436 #theme.display_outline_color436 #theme.display_outline_color
437 theme.display_shadow = str_to_bool(theme.display_shadow)437 theme.display_shadow = str_to_bool(theme.display_shadow)
438 #theme.display_shadow_color438 #theme.display_shadow_color
439 theme.display_verticalAlign = theme.display_verticalAlign.strip()439 theme.display_verticalAlign = theme.display_verticalAlign.strip()
440 theme.display_wrapStyle = theme.display_wrapStyle.strip()440 theme.display_wrapStyle = theme.display_wrapStyle.strip()
441 theme.font_footer_color = theme.font_footer_color.strip()441 theme.font_footer_color = theme.font_footer_color.strip()
442 theme.font_footer_height = theme.font_footer_height.strip()442 theme.font_footer_height = theme.font_footer_height.strip()
443 theme.font_footer_italics = str_to_bool(theme.font_footer_italics)443 theme.font_footer_italics = str_to_bool(theme.font_footer_italics)
444 theme.font_footer_name = theme.font_footer_name.strip()444 theme.font_footer_name = theme.font_footer_name.strip()
445 #theme.font_footer_override445 #theme.font_footer_override
446 theme.font_footer_proportion = theme.font_footer_proportion.strip()446 theme.font_footer_proportion = theme.font_footer_proportion.strip()
447 theme.font_footer_weight = theme.font_footer_weight.strip()447 theme.font_footer_weight = theme.font_footer_weight.strip()
448 theme.font_footer_width = theme.font_footer_width.strip()448 theme.font_footer_width = theme.font_footer_width.strip()
449 theme.font_footer_x = theme.font_footer_x.strip()449 theme.font_footer_x = theme.font_footer_x.strip()
450 theme.font_footer_y = theme.font_footer_y.strip()450 theme.font_footer_y = theme.font_footer_y.strip()
451 theme.font_main_color = theme.font_main_color.strip()451 theme.font_main_color = theme.font_main_color.strip()
452 theme.font_main_height = theme.font_main_height.strip()452 theme.font_main_height = theme.font_main_height.strip()
453 theme.font_main_italics = str_to_bool(theme.font_main_italics)453 theme.font_main_italics = str_to_bool(theme.font_main_italics)
454 theme.font_main_name = theme.font_main_name.strip()454 theme.font_main_name = theme.font_main_name.strip()
455 #theme.font_main_override455 #theme.font_main_override
456 theme.font_main_proportion = theme.font_main_proportion.strip()456 theme.font_main_proportion = theme.font_main_proportion.strip()
457 theme.font_main_weight = theme.font_main_weight.strip()457 theme.font_main_weight = theme.font_main_weight.strip()
458 theme.font_main_x = theme.font_main_x.strip()458 theme.font_main_x = theme.font_main_x.strip()
459 theme.font_main_y = theme.font_main_y.strip()459 theme.font_main_y = theme.font_main_y.strip()
460 #theme.theme_mode460 #theme.theme_mode
461 theme.theme_name = theme.theme_name.strip()461 theme.theme_name = theme.theme_name.strip()
462 #theme.theme_version462 #theme.theme_version
463463
=== modified file 'openlp/plugins/bibles/test/biblebooks_msg_short.csv'
--- openlp/plugins/bibles/test/biblebooks_msg_short.csv 2008-12-10 19:11:00 +0000
+++ openlp/plugins/bibles/test/biblebooks_msg_short.csv 2009-09-13 15:14:45 +0000
@@ -1,8 +1,8 @@
11,1,"Genesis","GEN"11,1,"Genesis","GEN"
22,1,"Exodus","EXOD"22,1,"Exodus","EXOD"
33,1,"Leviticus","LEV"33,1,"Leviticus","LEV"
44,1,"Numbers","NUM"44,1,"Numbers","NUM"
547,2,"Matthew","MATT"547,2,"Matthew","MATT"
648,2,"Mark","MARK"648,2,"Mark","MARK"
749,2,"Luke","LUKE"749,2,"Luke","LUKE"
850,2,"John","JOHN"850,2,"John","JOHN"
99
=== modified file 'openlp/plugins/bibles/test/biblebooks_niv_short.csv'
--- openlp/plugins/bibles/test/biblebooks_niv_short.csv 2008-12-10 19:11:00 +0000
+++ openlp/plugins/bibles/test/biblebooks_niv_short.csv 2009-09-13 15:14:45 +0000
@@ -1,9 +1,9 @@
11,1,"Genesis","GEN"11,1,"Genesis","GEN"
22,1,"Exodus","EXOD"22,1,"Exodus","EXOD"
33,1,"Leviticus","LEV"33,1,"Leviticus","LEV"
44,1,"Numbers","NUM"44,1,"Numbers","NUM"
546,1,"Malachi","MAL"546,1,"Malachi","MAL"
647,2,"Matthew","MATT"647,2,"Matthew","MATT"
748,2,"Mark","MARK"748,2,"Mark","MARK"
849,2,"Luke","LUKE"849,2,"Luke","LUKE"
950,2,"John","JOHN"950,2,"John","JOHN"
1010
=== modified file 'openlp/plugins/bibles/test/bibleverses_msg_short.csv'
--- openlp/plugins/bibles/test/bibleverses_msg_short.csv 2008-12-10 19:11:00 +0000
+++ openlp/plugins/bibles/test/bibleverses_msg_short.csv 2009-09-13 15:14:45 +0000
@@ -1,35 +1,35 @@
1"Genesis",1,1,"First this: God created the Heavens and Earth - all you see, all you don't see."1"Genesis",1,1,"First this: God created the Heavens and Earth - all you see, all you don't see."
2"Genesis",1,2,"Earth was a soup of nothingness, a bottomless emptiness, an inky blackness. God's Spirit brooded like a bird above the watery abyss."2"Genesis",1,2,"Earth was a soup of nothingness, a bottomless emptiness, an inky blackness. God's Spirit brooded like a bird above the watery abyss."
3"Exodus",1,1,"These are the names of the Israelites who went to Egypt with Jacob, each bringing his family members:"3"Exodus",1,1,"These are the names of the Israelites who went to Egypt with Jacob, each bringing his family members:"
4"Exodus",1,2,"Reuben, Simeon, Levi, and Judah,"4"Exodus",1,2,"Reuben, Simeon, Levi, and Judah,"
5"Exodus",2,1,"A man from the family of Levi married a Levite woman."5"Exodus",2,1,"A man from the family of Levi married a Levite woman."
6"Exodus",2,2,"The woman became pregnant and had a son. She saw there was something special about him and hid him. She hid him for three months."6"Exodus",2,2,"The woman became pregnant and had a son. She saw there was something special about him and hid him. She hid him for three months."
7"Leviticus",1,1,"God called Moses and spoke to him from the Tent of Meeting:"7"Leviticus",1,1,"God called Moses and spoke to him from the Tent of Meeting:"
8"Leviticus",1,2,"""Speak to the People of Israel. Tell them, When anyone presents an offering to God, present an animal from either the herd or the flock."8"Leviticus",1,2,"""Speak to the People of Israel. Tell them, When anyone presents an offering to God, present an animal from either the herd or the flock."
9"Leviticus",1,3,"""If the offering is a Whole-Burnt-Offering from the herd, present a male without a defect at the entrance to the Tent of Meeting that it may be accepted by God."9"Leviticus",1,3,"""If the offering is a Whole-Burnt-Offering from the herd, present a male without a defect at the entrance to the Tent of Meeting that it may be accepted by God."
10"Numbers",1,1,"God spoke to Moses in the Wilderness of Sinai at the Tent of Meeting on the first day of the second month in the second year after they had left Egypt. He said,"10"Numbers",1,1,"God spoke to Moses in the Wilderness of Sinai at the Tent of Meeting on the first day of the second month in the second year after they had left Egypt. He said,"
11"Numbers",1,2,"""Number the congregation of the People of Israel by clans and families, writing down the names of every male."11"Numbers",1,2,"""Number the congregation of the People of Israel by clans and families, writing down the names of every male."
12"Matthew",1,1,"The family tree of Jesus Christ, David's son, Abraham's son:"12"Matthew",1,1,"The family tree of Jesus Christ, David's son, Abraham's son:"
13"Matthew",1,2,"Abraham had Isaac, Isaac had Jacob, Jacob had Judah and his brothers,"13"Matthew",1,2,"Abraham had Isaac, Isaac had Jacob, Jacob had Judah and his brothers,"
14"Matthew",1,3,"Judah had Perez and Zerah (the mother was Tamar), Perez had Hezron, Hezron had Aram,"14"Matthew",1,3,"Judah had Perez and Zerah (the mother was Tamar), Perez had Hezron, Hezron had Aram,"
15"Matthew",1,4,"Aram had Amminadab, Amminadab had Nahshon, Nahshon had Salmon,"15"Matthew",1,4,"Aram had Amminadab, Amminadab had Nahshon, Nahshon had Salmon,"
16"Matthew",1,5,"Salmon had Boaz (his mother was Rahab), Boaz had Obed (Ruth was the mother), Obed had Jesse,"16"Matthew",1,5,"Salmon had Boaz (his mother was Rahab), Boaz had Obed (Ruth was the mother), Obed had Jesse,"
17"Matthew",1,6,"Jesse had David, and David became king. David had Solomon (Uriah's wife was the mother),"17"Matthew",1,6,"Jesse had David, and David became king. David had Solomon (Uriah's wife was the mother),"
18"Matthew",1,7,"Solomon had Rehoboam, Rehoboam had Abijah, Abijah had Asa,"18"Matthew",1,7,"Solomon had Rehoboam, Rehoboam had Abijah, Abijah had Asa,"
19"Matthew",1,8,"Asa had Jehoshaphat, Jehoshaphat had Joram, Joram had Uzziah,"19"Matthew",1,8,"Asa had Jehoshaphat, Jehoshaphat had Joram, Joram had Uzziah,"
20"Matthew",2,1,"After Jesus was born in Bethlehem village, Judah territory - this was during Herod's kingship - a band of scholars arrived in Jerusalem from the East."20"Matthew",2,1,"After Jesus was born in Bethlehem village, Judah territory - this was during Herod's kingship - a band of scholars arrived in Jerusalem from the East."
21"Matthew",2,2,"They asked around, ""Where can we find and pay homage to the newborn King of the Jews? We observed a star in the eastern sky that "Matthew",3,1,"While Jesus was living in the Galilean hills, John, called ""the Baptizer,"" was preaching in the desert country of Judea."21"Matthew",2,2,"They asked around, ""Where can we find and pay homage to the newborn King of the Jews? We observed a star in the eastern sky that "Matthew",3,1,"While Jesus was living in the Galilean hills, John, called ""the Baptizer,"" was preaching in the desert country of Judea."
22"Matthew",3,2,"His message was simple and austere, like his desert surroundings: ""Change your life. God's kingdom is here."""22"Matthew",3,2,"His message was simple and austere, like his desert surroundings: ""Change your life. God's kingdom is here."""
23"Matthew",3,3,"John and his message were authorized by Isaiah's prophecy: Thunder in the desert! Prepare for God's arrival! Make the road smooth and straight!"23"Matthew",3,3,"John and his message were authorized by Isaiah's prophecy: Thunder in the desert! Prepare for God's arrival! Make the road smooth and straight!"
24"Mark",1,1,"The good news of Jesus Christ - the Message! - begins here,"24"Mark",1,1,"The good news of Jesus Christ - the Message! - begins here,"
25"Mark",1,2,"following to the letter the scroll of the prophet Isaiah. Watch closely: I'm sending my preacher ahead of you; He'll make the road smooth for you."25"Mark",1,2,"following to the letter the scroll of the prophet Isaiah. Watch closely: I'm sending my preacher ahead of you; He'll make the road smooth for you."
26"Mark",1,3,"Thunder in the desert! Prepare for God's arrival! Make the road smooth and straight!"26"Mark",1,3,"Thunder in the desert! Prepare for God's arrival! Make the road smooth and straight!"
27"Luke",1,1,"So many others have tried their hand at putting together a story of the wonderful harvest of Scripture and history that took place among us,"27"Luke",1,1,"So many others have tried their hand at putting together a story of the wonderful harvest of Scripture and history that took place among us,"
28"Luke",1,2,"using reports handed down by the original eyewitnesses who served this Word with their very lives."28"Luke",1,2,"using reports handed down by the original eyewitnesses who served this Word with their very lives."
29"Luke",1,3,"Since I have investigated all the reports in close detail, starting from the story's beginning, I decided to write it all out for you, most honorable Theophilus,"29"Luke",1,3,"Since I have investigated all the reports in close detail, starting from the story's beginning, I decided to write it all out for you, most honorable Theophilus,"
30"John",1,1,"The Word was first, the Word present to God, God present to the Word. The Word was God,"30"John",1,1,"The Word was first, the Word present to God, God present to the Word. The Word was God,"
31"John",1,2,"in readiness for God from day one."31"John",1,2,"in readiness for God from day one."
32"John",1,3,"Everything was created through him; nothing - not one thing! - came into being without him."32"John",1,3,"Everything was created through him; nothing - not one thing! - came into being without him."
33"John",2,1,"Three days later there was a wedding in the village of Cana in Galilee. Jesus' mother was there."33"John",2,1,"Three days later there was a wedding in the village of Cana in Galilee. Jesus' mother was there."
34"John",2,2,"Jesus and his disciples were guests also."34"John",2,2,"Jesus and his disciples were guests also."
35"John",2,3,"When they started running low on wine at the wedding banquet, Jesus' mother told him, ""They're just about out of wine."""35"John",2,3,"When they started running low on wine at the wedding banquet, Jesus' mother told him, ""They're just about out of wine."""
3636
=== modified file 'openlp/plugins/presentations/lib/pptviewlib/README.TXT'
--- openlp/plugins/presentations/lib/pptviewlib/README.TXT 2008-12-10 20:40:18 +0000
+++ openlp/plugins/presentations/lib/pptviewlib/README.TXT 2009-09-13 15:14:45 +0000
@@ -1,116 +1,116 @@
11
2PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org)2PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org)
3Copyright (C) 2008 Jonathan Corwin (j@corwin.co.uk)3Copyright (C) 2008 Jonathan Corwin (j@corwin.co.uk)
4 4
5This library wrappers the free Microsoft PowerPoint Viewer (2003/2007) program, 5This library wrappers the free Microsoft PowerPoint Viewer (2003/2007) program,
6allowing it to be more easily controlled from another program. 6allowing it to be more easily controlled from another program.
77
8The PowerPoint Viewer must already be installed on the destination machine, and is 8The PowerPoint Viewer must already be installed on the destination machine, and is
9freely available at microsoft.com.9freely available at microsoft.com.
1010
11The full Microsoft Office PowerPoint and PowerPoint Viewer 97 have a COM interface allowing11The full Microsoft Office PowerPoint and PowerPoint Viewer 97 have a COM interface allowing
12automation. This ability was removed from the 2003+ viewer offerings.12automation. This ability was removed from the 2003+ viewer offerings.
1313
14To developers: I am not a C/C++ or Win32 API programmer as you can probably tell. 14To developers: I am not a C/C++ or Win32 API programmer as you can probably tell.
15The code and API of this DLL could certainly do with some tidying up, and the15The code and API of this DLL could certainly do with some tidying up, and the
16error trapping, where it exists, is very basic. I'll happily accept patches!16error trapping, where it exists, is very basic. I'll happily accept patches!
1717
18This library is covered by the GPL (http://www.gnu.org/licenses/)18This library is covered by the GPL (http://www.gnu.org/licenses/)
19It is NOT covered by the LGPL, so can only be used in GPL compatable programs.19It is NOT covered by the LGPL, so can only be used in GPL compatable programs.
20(http://www.gnu.org/licenses/why-not-lgpl.html)20(http://www.gnu.org/licenses/why-not-lgpl.html)
2121
22This README.TXT must be distributed with the pptviewlib.dll22This README.TXT must be distributed with the pptviewlib.dll
2323
24This library has a limit of 50 PowerPoints which can be opened simultaneously.24This library has a limit of 50 PowerPoints which can be opened simultaneously.
2525
26USAGE26USAGE
27-----27-----
28int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);28int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);
2929
30 Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly30 Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly
31 and creates preview images of each slide. Note PowerPoint Viewer only allows the 31 and creates preview images of each slide. Note PowerPoint Viewer only allows the
32 slideshow to be resized whilst it is being loaded. It can be moved at any time however.32 slideshow to be resized whilst it is being loaded. It can be moved at any time however.
3333
34 The only way to count the number of slides is to step through the entire show. Therefore34 The only way to count the number of slides is to step through the entire show. Therefore
35 there will be a delay whilst opening large presentations for the first time.35 there will be a delay whilst opening large presentations for the first time.
36 For pre XP/2003 systems, the slideshow will flicker as the screen snapshots are taken.36 For pre XP/2003 systems, the slideshow will flicker as the screen snapshots are taken.
3737
38 filename: The PowerPoint file to be opened. Full path38 filename: The PowerPoint file to be opened. Full path
39 hParentWnd: The window which will become the parent of the slideshow window. 39 hParentWnd: The window which will become the parent of the slideshow window.
40 Can be NULL.40 Can be NULL.
41 rect: The location/dimensions of the slideshow window. 41 rect: The location/dimensions of the slideshow window.
42 If all properties of this structure are zero, the dimensions of the hParentWnd42 If all properties of this structure are zero, the dimensions of the hParentWnd
43 are used. 43 are used.
44 previewpath If specified, the prefix to use for snapshot images of each slide, in the 44 previewpath If specified, the prefix to use for snapshot images of each slide, in the
45 form: previewpath + n + ".bmp", where n is the slide number.45 form: previewpath + n + ".bmp", where n is the slide number.
46 A file called previewpath + "info.txt" will also be created containing information46 A file called previewpath + "info.txt" will also be created containing information
47 about the PPT file, to speed up future openings of the unmodified file.47 about the PPT file, to speed up future openings of the unmodified file.
48 Note it is up the calling program to directly access these images if they 48 Note it is up the calling program to directly access these images if they
49 are required.49 are required.
5050
51 RETURNS: An unique identifier to pass to other methods in this library.51 RETURNS: An unique identifier to pass to other methods in this library.
52 If < 0, then the PPT failed to open.52 If < 0, then the PPT failed to open.
53 If >=0, ClosePPT must be called when the PPT is no longer being used53 If >=0, ClosePPT must be called when the PPT is no longer being used
54 or when the calling program is closed to release resources/hooks.54 or when the calling program is closed to release resources/hooks.
55 55
56void ClosePPT(int id);56void ClosePPT(int id);
57 Closes the presentation, releasing any resources and hooks.57 Closes the presentation, releasing any resources and hooks.
5858
59 id: The value returned from OpenPPT.59 id: The value returned from OpenPPT.
60 60
61int GetCurrentSlide(int id);61int GetCurrentSlide(int id);
62 Returns the current slide number (from 1)62 Returns the current slide number (from 1)
6363
64 id: The value returned from OpenPPT.64 id: The value returned from OpenPPT.
6565
66int GetSlideCount(int id);66int GetSlideCount(int id);
67 Returns the total number of slides.67 Returns the total number of slides.
6868
69 id: The value returned from OpenPPT.69 id: The value returned from OpenPPT.
7070
71void NextStep(int id);71void NextStep(int id);
72 Advances one step (animation) through the slideshow.72 Advances one step (animation) through the slideshow.
7373
74 id: The value returned from OpenPPT.74 id: The value returned from OpenPPT.
7575
76void PrevStep(int id);76void PrevStep(int id);
77 Goes backwards one step (animation) through the slideshow.77 Goes backwards one step (animation) through the slideshow.
7878
79 id: The value returned from OpenPPT.79 id: The value returned from OpenPPT.
8080
81void GotoSlide(int id, int slideno);81void GotoSlide(int id, int slideno);
82 Goes directly to a specific slide in the slideshow82 Goes directly to a specific slide in the slideshow
8383
84 id: The value returned from OpenPPT.84 id: The value returned from OpenPPT.
85 slideno: The number of the slide (from 1) to go directly to.85 slideno: The number of the slide (from 1) to go directly to.
86 86
87 If the slide has already been displayed, then the completed slide with animations performed87 If the slide has already been displayed, then the completed slide with animations performed
88 will be shown. This is how the PowerPoint Viewer works so have no control over this.88 will be shown. This is how the PowerPoint Viewer works so have no control over this.
8989
90void RestartShow(int id);90void RestartShow(int id);
91 Restarts the show from the beginning. To reset animations, behind the scenes it 91 Restarts the show from the beginning. To reset animations, behind the scenes it
92 has to travel to the end and step backwards though the entire show. Therefore92 has to travel to the end and step backwards though the entire show. Therefore
93 for large presentations there might be a delay.93 for large presentations there might be a delay.
9494
95 id: The value returned from OpenPPT.95 id: The value returned from OpenPPT.
9696
97void Blank(int id);97void Blank(int id);
98 Blanks the screen, colour black.98 Blanks the screen, colour black.
9999
100 id: The value returned from OpenPPT.100 id: The value returned from OpenPPT.
101101
102void Unblank(int id)102void Unblank(int id)
103 Unblanks the screen, restoring it to it's pre-blank state.103 Unblanks the screen, restoring it to it's pre-blank state.
104 104
105 id: The value returned from OpenPPT.105 id: The value returned from OpenPPT.
106106
107void Stop(int id)107void Stop(int id)
108 Moves the slideshow off the screen. (There is no concept of stop show in the PowerPoint Viewer)108 Moves the slideshow off the screen. (There is no concept of stop show in the PowerPoint Viewer)
109109
110 id: The value returned from OpenPPT.110 id: The value returned from OpenPPT.
111111
112void Resume(int id)112void Resume(int id)
113 Moves the slideshow display back onto the screen following a Stop()113 Moves the slideshow display back onto the screen following a Stop()
114114
115 id: The value returned from OpenPPT.115 id: The value returned from OpenPPT.
116116
117117
=== modified file 'openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp'
--- openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp 2008-12-10 20:40:18 +0000
+++ openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp 2009-09-13 15:14:45 +0000
@@ -1,753 +1,753 @@
1/*1/*
2 * PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org)2 * PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org)
3 * Copyright (C) 2008 Jonathan Corwin3 * Copyright (C) 2008 Jonathan Corwin
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.8 * (at your option) any later version.
9 *9 *
10 * This program is distributed in the hope that it will be useful,10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.13 * GNU General Public License for more details.
14 *14 *
15 * You should have received a copy of the GNU General Public License15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */17 */
1818
1919
20#define WIN32_LEAN_AND_MEAN 20#define WIN32_LEAN_AND_MEAN
21#include <windows.h>21#include <windows.h>
22#include <string.h>22#include <string.h>
23#include <stdlib.h>23#include <stdlib.h>
24#include <stdio.h>24#include <stdio.h>
25#include <time.h>25#include <time.h>
26#include <sys/types.h>26#include <sys/types.h>
27#include <sys/stat.h>27#include <sys/stat.h>
28#include "pptviewlib.h"28#include "pptviewlib.h"
2929
30// Because of the callbacks used by SetWindowsHookEx, the memory used needs to be30// Because of the callbacks used by SetWindowsHookEx, the memory used needs to be
31// sharable across processes (the callbacks are done from a different process)31// sharable across processes (the callbacks are done from a different process)
32// Therefore use data_seg with RWS memory.32// Therefore use data_seg with RWS memory.
33//33//
34// See http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx for alternative34// See http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx for alternative
35// method of holding memory, removing fixed limits which would allow dynamic number35// method of holding memory, removing fixed limits which would allow dynamic number
36// of items, rather than a fixed number. Use a Local\ mapping, since global has UAC 36// of items, rather than a fixed number. Use a Local\ mapping, since global has UAC
37// issues in Vista.37// issues in Vista.
38#pragma data_seg(".PPTVIEWLIB")38#pragma data_seg(".PPTVIEWLIB")
39PPTVIEWOBJ pptviewobj[MAX_PPTOBJS] = {NULL};39PPTVIEWOBJ pptviewobj[MAX_PPTOBJS] = {NULL};
40HHOOK globalhook = NULL;40HHOOK globalhook = NULL;
41BOOL debug = FALSE;41BOOL debug = FALSE;
42#pragma data_seg()42#pragma data_seg()
43#pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS")43#pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS")
4444
45#define DEBUG(...) if(debug) printf(__VA_ARGS__)45#define DEBUG(...) if(debug) printf(__VA_ARGS__)
4646
4747
48HINSTANCE hInstance = NULL;48HINSTANCE hInstance = NULL;
4949
50BOOL APIENTRY DllMain( HMODULE hModule,50BOOL APIENTRY DllMain( HMODULE hModule,
51 DWORD ul_reason_for_call,51 DWORD ul_reason_for_call,
52 LPVOID lpReserved52 LPVOID lpReserved
53 )53 )
54{54{
55 hInstance = (HINSTANCE)hModule;55 hInstance = (HINSTANCE)hModule;
56 switch (ul_reason_for_call)56 switch (ul_reason_for_call)
57 {57 {
58 case DLL_PROCESS_ATTACH:58 case DLL_PROCESS_ATTACH:
59 DEBUG("PROCESS_ATTACH\n");59 DEBUG("PROCESS_ATTACH\n");
60 break;60 break;
61 case DLL_THREAD_ATTACH:61 case DLL_THREAD_ATTACH:
62 DEBUG("THREAD_ATTACH\n");62 DEBUG("THREAD_ATTACH\n");
63 break;63 break;
64 case DLL_THREAD_DETACH:64 case DLL_THREAD_DETACH:
65 DEBUG("THREAD_DETACH\n");65 DEBUG("THREAD_DETACH\n");
66 break;66 break;
67 case DLL_PROCESS_DETACH:67 case DLL_PROCESS_DETACH:
68 // Clean up... hopefully there is only the one process attached? 68 // Clean up... hopefully there is only the one process attached?
69 // We'll find out soon enough during tests!69 // We'll find out soon enough during tests!
70 DEBUG("PROCESS_DETACH\n");70 DEBUG("PROCESS_DETACH\n");
71 for(int i = 0; i<MAX_PPTOBJS; i++)71 for(int i = 0; i<MAX_PPTOBJS; i++)
72 ClosePPT(i);72 ClosePPT(i);
73 break;73 break;
74 }74 }
75 return TRUE;75 return TRUE;
76}76}
77DllExport void SetDebug(BOOL onoff)77DllExport void SetDebug(BOOL onoff)
78{78{
79 printf("SetDebug\n");79 printf("SetDebug\n");
80 debug = onoff;80 debug = onoff;
81 DEBUG("enabled\n");81 DEBUG("enabled\n");
82}82}
8383
84// Open the PointPoint, count the slides and take a snapshot of each slide84// Open the PointPoint, count the slides and take a snapshot of each slide
85// for use in previews85// for use in previews
86// previewpath is a prefix for the location to put preview images of each slide.86// previewpath is a prefix for the location to put preview images of each slide.
87// "<n>.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would 87// "<n>.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would
88// create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc.88// create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc.
89// It will also create a *info.txt containing information about the ppt89// It will also create a *info.txt containing information about the ppt
90DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath)90DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath)
91{91{
92 STARTUPINFO si;92 STARTUPINFO si;
93 PROCESS_INFORMATION pi;93 PROCESS_INFORMATION pi;
94 char cmdline[MAX_PATH * 2];94 char cmdline[MAX_PATH * 2];
95 int id;95 int id;
9696
97 DEBUG("OpenPPT start: %s; %s\n", filename, previewpath);97 DEBUG("OpenPPT start: %s; %s\n", filename, previewpath);
98 DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top, rect.left, rect.bottom, rect.right);98 DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top, rect.left, rect.bottom, rect.right);
99 if(GetPPTViewerPath(cmdline, sizeof(cmdline))==FALSE)99 if(GetPPTViewerPath(cmdline, sizeof(cmdline))==FALSE)
100 {100 {
101 DEBUG("OpenPPT: GetPPTViewerPath failed\n");101 DEBUG("OpenPPT: GetPPTViewerPath failed\n");
102 return -1;102 return -1;
103 }103 }
104 id = -1;104 id = -1;
105 for(int i = 0; i<MAX_PPTOBJS; i++)105 for(int i = 0; i<MAX_PPTOBJS; i++)
106 {106 {
107 if(pptviewobj[i].state==PPT_CLOSED)107 if(pptviewobj[i].state==PPT_CLOSED)
108 {108 {
109 id=i;109 id=i;
110 break;110 break;
111 }111 }
112 }112 }
113 if(id<0)113 if(id<0)
114 {114 {
115 DEBUG("OpenPPT: Too many PPTs\n");115 DEBUG("OpenPPT: Too many PPTs\n");
116 return -1;116 return -1;
117 }117 }
118 memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ));118 memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ));
119 strcpy_s(pptviewobj[id].filename, MAX_PATH, filename);119 strcpy_s(pptviewobj[id].filename, MAX_PATH, filename);
120 strcpy_s(pptviewobj[id].previewpath, MAX_PATH, previewpath);120 strcpy_s(pptviewobj[id].previewpath, MAX_PATH, previewpath);
121 pptviewobj[id].state = PPT_CLOSED;121 pptviewobj[id].state = PPT_CLOSED;
122 pptviewobj[id].slideCount = 0;122 pptviewobj[id].slideCount = 0;
123 pptviewobj[id].currentSlide = 0;123 pptviewobj[id].currentSlide = 0;
124 pptviewobj[id].firstSlideSteps = 0;124 pptviewobj[id].firstSlideSteps = 0;
125 pptviewobj[id].hParentWnd = hParentWnd;125 pptviewobj[id].hParentWnd = hParentWnd;
126 pptviewobj[id].hWnd = NULL;126 pptviewobj[id].hWnd = NULL;
127 pptviewobj[id].hWnd2 = NULL;127 pptviewobj[id].hWnd2 = NULL;
128 if(hParentWnd!=NULL&&rect.top==0&&rect.bottom==0&&rect.left==0&&rect.right==0)128 if(hParentWnd!=NULL&&rect.top==0&&rect.bottom==0&&rect.left==0&&rect.right==0)
129 {129 {
130 LPRECT wndrect = NULL;130 LPRECT wndrect = NULL;
131 GetWindowRect(hParentWnd, wndrect);131 GetWindowRect(hParentWnd, wndrect);
132 pptviewobj[id].rect.top = 0;132 pptviewobj[id].rect.top = 0;
133 pptviewobj[id].rect.left = 0;133 pptviewobj[id].rect.left = 0;
134 pptviewobj[id].rect.bottom = wndrect->bottom-wndrect->top;134 pptviewobj[id].rect.bottom = wndrect->bottom-wndrect->top;
135 pptviewobj[id].rect.right = wndrect->right-wndrect->left;135 pptviewobj[id].rect.right = wndrect->right-wndrect->left;
136 }136 }
137 else137 else
138 {138 {
139 pptviewobj[id].rect.top = rect.top;139 pptviewobj[id].rect.top = rect.top;
140 pptviewobj[id].rect.left = rect.left;140 pptviewobj[id].rect.left = rect.left;
141 pptviewobj[id].rect.bottom = rect.bottom;141 pptviewobj[id].rect.bottom = rect.bottom;
142 pptviewobj[id].rect.right = rect.right;142 pptviewobj[id].rect.right = rect.right;
143 }143 }
144 strcat_s(cmdline, MAX_PATH * 2, "/S \"");144 strcat_s(cmdline, MAX_PATH * 2, "/S \"");
145 strcat_s(cmdline, MAX_PATH * 2, filename);145 strcat_s(cmdline, MAX_PATH * 2, filename);
146 strcat_s(cmdline, MAX_PATH * 2, "\"");146 strcat_s(cmdline, MAX_PATH * 2, "\"");
147 memset(&si, 0, sizeof(si));147 memset(&si, 0, sizeof(si));
148 memset(&pi, 0, sizeof(pi));148 memset(&pi, 0, sizeof(pi));
149 BOOL gotinfo = GetPPTInfo(id);149 BOOL gotinfo = GetPPTInfo(id);
150 /* 150 /*
151 * I'd really like to just hook on the new threadid. However this always gives151 * I'd really like to just hook on the new threadid. However this always gives
152 * error 87. Perhaps I'm hooking to soon? No idea... however can't wait152 * error 87. Perhaps I'm hooking to soon? No idea... however can't wait
153 * since I need to ensure I pick up the WM_CREATE as this is the only153 * since I need to ensure I pick up the WM_CREATE as this is the only
154 * time the window can be resized in such away the content scales correctly154 * time the window can be resized in such away the content scales correctly
155 *155 *
156 * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId);156 * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId);
157 */157 */
158 if(globalhook!=NULL)158 if(globalhook!=NULL)
159 UnhookWindowsHookEx(globalhook);159 UnhookWindowsHookEx(globalhook);
160 globalhook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,NULL);160 globalhook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,NULL);
161 if(globalhook==0)161 if(globalhook==0)
162 {162 {
163 DEBUG("OpenPPT: SetWindowsHookEx failed\n");163 DEBUG("OpenPPT: SetWindowsHookEx failed\n");
164 ClosePPT(id);164 ClosePPT(id);
165 return -1;165 return -1;
166 }166 }
167 pptviewobj[id].state = PPT_STARTED;167 pptviewobj[id].state = PPT_STARTED;
168 Sleep(10); 168 Sleep(10);
169 if(!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi))169 if(!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi))
170 {170 {
171 DEBUG("OpenPPT: CreateProcess failed\n");171 DEBUG("OpenPPT: CreateProcess failed\n");
172 ClosePPT(id);172 ClosePPT(id);
173 return -1;173 return -1;
174 }174 }
175 pptviewobj[id].dwProcessId = pi.dwProcessId;175 pptviewobj[id].dwProcessId = pi.dwProcessId;
176 pptviewobj[id].dwThreadId = pi.dwThreadId;176 pptviewobj[id].dwThreadId = pi.dwThreadId;
177 pptviewobj[id].hThread = pi.hThread;177 pptviewobj[id].hThread = pi.hThread;
178 pptviewobj[id].hProcess = pi.hProcess;178 pptviewobj[id].hProcess = pi.hProcess;
179 while(pptviewobj[id].state==PPT_STARTED)179 while(pptviewobj[id].state==PPT_STARTED)
180 Sleep(10);180 Sleep(10);
181 if(gotinfo)181 if(gotinfo)
182 {182 {
183 DEBUG("OpenPPT: Info loaded, no refresh\n");183 DEBUG("OpenPPT: Info loaded, no refresh\n");
184 pptviewobj[id].state = PPT_LOADED;184 pptviewobj[id].state = PPT_LOADED;
185 Resume(id);185 Resume(id);
186 }186 }
187 else187 else
188 {188 {
189 DEBUG("OpenPPT: Get info\n");189 DEBUG("OpenPPT: Get info\n");
190 pptviewobj[id].steps = 0;190 pptviewobj[id].steps = 0;
191 int steps = 0;191 int steps = 0;
192 while(pptviewobj[id].state==PPT_OPENED)192 while(pptviewobj[id].state==PPT_OPENED)
193 {193 {
194 if(steps<=pptviewobj[id].steps)194 if(steps<=pptviewobj[id].steps)
195 {195 {
196 Sleep(20);196 Sleep(20);
197 DEBUG("OpenPPT: Step %d/%d\n",steps,pptviewobj[id].steps);197 DEBUG("OpenPPT: Step %d/%d\n",steps,pptviewobj[id].steps);
198 steps++;198 steps++;
199 NextStep(id);199 NextStep(id);
200 } 200 }
201 Sleep(10);201 Sleep(10);
202 }202 }
203 DEBUG("OpenPPT: Steps %d, first slide steps %d\n",pptviewobj[id].steps,pptviewobj[id].firstSlideSteps);203 DEBUG("OpenPPT: Steps %d, first slide steps %d\n",pptviewobj[id].steps,pptviewobj[id].firstSlideSteps);
204 SavePPTInfo(id);204 SavePPTInfo(id);
205 if(pptviewobj[id].state==PPT_CLOSING){205 if(pptviewobj[id].state==PPT_CLOSING){
206 ClosePPT(id);206 ClosePPT(id);
207 id=-1;207 id=-1;
208 }208 }
209 else209 else
210 RestartShow(id);210 RestartShow(id);
211 }211 }
212 if(id>=0)212 if(id>=0)
213 {213 {
214 if(pptviewobj[id].mhook!=NULL) 214 if(pptviewobj[id].mhook!=NULL)
215 UnhookWindowsHookEx(pptviewobj[id].mhook);215 UnhookWindowsHookEx(pptviewobj[id].mhook);
216 pptviewobj[id].mhook = NULL;216 pptviewobj[id].mhook = NULL;
217 }217 }
218 DEBUG("OpenPPT: Exit: id=%i\n", id);218 DEBUG("OpenPPT: Exit: id=%i\n", id);
219 return id;219 return id;
220}220}
221// Load information about the ppt from an info.txt file.221// Load information about the ppt from an info.txt file.
222// Format:222// Format:
223// version223// version
224// filedate224// filedate
225// filesize225// filesize
226// slidecount226// slidecount
227// first slide steps227// first slide steps
228BOOL GetPPTInfo(int id)228BOOL GetPPTInfo(int id)
229{229{
230 struct _stat filestats;230 struct _stat filestats;
231 char info[MAX_PATH];231 char info[MAX_PATH];
232 FILE* pFile;232 FILE* pFile;
233 char buf[100];233 char buf[100];
234234
235 DEBUG("GetPPTInfo: start\n");235 DEBUG("GetPPTInfo: start\n");
236 if(_stat(pptviewobj[id].filename, &filestats)!=0)236 if(_stat(pptviewobj[id].filename, &filestats)!=0)
237 return FALSE;237 return FALSE;
238 sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath);238 sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath);
239 int err = fopen_s(&pFile, info, "r");239 int err = fopen_s(&pFile, info, "r");
240 if(err!=0)240 if(err!=0)
241 {241 {
242 DEBUG("GetPPTInfo: file open failed - %d\n", err);242 DEBUG("GetPPTInfo: file open failed - %d\n", err);
243 return FALSE;243 return FALSE;
244 }244 }
245 fgets(buf, 100, pFile); // version == 1245 fgets(buf, 100, pFile); // version == 1
246 fgets(buf, 100, pFile); 246 fgets(buf, 100, pFile);
247 if(filestats.st_mtime!=atoi(buf))247 if(filestats.st_mtime!=atoi(buf))
248 {248 {
249 fclose (pFile);249 fclose (pFile);
250 return FALSE;250 return FALSE;
251 }251 }
252 fgets(buf, 100, pFile); 252 fgets(buf, 100, pFile);
253 if(filestats.st_size!=atoi(buf))253 if(filestats.st_size!=atoi(buf))
254 {254 {
255 fclose (pFile);255 fclose (pFile);
256 return FALSE;256 return FALSE;
257 }257 }
258 fgets(buf, 100, pFile); // slidecount258 fgets(buf, 100, pFile); // slidecount
259 int slidecount = atoi(buf);259 int slidecount = atoi(buf);
260 fgets(buf, 100, pFile); // first slide steps260 fgets(buf, 100, pFile); // first slide steps
261 int firstslidesteps = atoi(buf);261 int firstslidesteps = atoi(buf);
262 // check all the preview images still exist262 // check all the preview images still exist
263 for(int i = 1; i<=slidecount; i++)263 for(int i = 1; i<=slidecount; i++)
264 {264 {
265 sprintf_s(info, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, i);265 sprintf_s(info, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, i);
266 if(GetFileAttributes(info)==INVALID_FILE_ATTRIBUTES)266 if(GetFileAttributes(info)==INVALID_FILE_ATTRIBUTES)
267 return FALSE;267 return FALSE;
268 }268 }
269 fclose(pFile);269 fclose(pFile);
270 pptviewobj[id].slideCount = slidecount;270 pptviewobj[id].slideCount = slidecount;
271 pptviewobj[id].firstSlideSteps = firstslidesteps;271 pptviewobj[id].firstSlideSteps = firstslidesteps;
272 DEBUG("GetPPTInfo: exit ok\n");272 DEBUG("GetPPTInfo: exit ok\n");
273 return TRUE;273 return TRUE;
274}274}
275275
276BOOL SavePPTInfo(int id)276BOOL SavePPTInfo(int id)
277{277{
278 struct _stat filestats;278 struct _stat filestats;
279 char info[MAX_PATH];279 char info[MAX_PATH];
280 FILE* pFile;280 FILE* pFile;
281281
282 DEBUG("SavePPTInfo: start\n");282 DEBUG("SavePPTInfo: start\n");
283 if(_stat(pptviewobj[id].filename, &filestats)!=0)283 if(_stat(pptviewobj[id].filename, &filestats)!=0)
284 {284 {
285 DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename);285 DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename);
286 return FALSE;286 return FALSE;
287 }287 }
288 sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath);288 sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath);
289 int err = fopen_s(&pFile, info, "w");289 int err = fopen_s(&pFile, info, "w");
290 if(err!=0)290 if(err!=0)
291 {291 {
292 DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err);292 DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err);
293 return FALSE;293 return FALSE;
294 }294 }
295 fprintf(pFile, "1\n");295 fprintf(pFile, "1\n");
296 fprintf(pFile, "%u\n", filestats.st_mtime);296 fprintf(pFile, "%u\n", filestats.st_mtime);
297 fprintf(pFile, "%u\n", filestats.st_size);297 fprintf(pFile, "%u\n", filestats.st_size);
298 fprintf(pFile, "%u\n", pptviewobj[id].slideCount);298 fprintf(pFile, "%u\n", pptviewobj[id].slideCount);
299 fprintf(pFile, "%u\n", pptviewobj[id].firstSlideSteps);299 fprintf(pFile, "%u\n", pptviewobj[id].firstSlideSteps);
300 fclose (pFile);300 fclose (pFile);
301 DEBUG("SavePPTInfo: exit ok\n");301 DEBUG("SavePPTInfo: exit ok\n");
302 return TRUE;302 return TRUE;
303}303}
304304
305// Get the path of the PowerPoint viewer from the registry305// Get the path of the PowerPoint viewer from the registry
306BOOL GetPPTViewerPath(char *pptviewerpath, int strsize)306BOOL GetPPTViewerPath(char *pptviewerpath, int strsize)
307{307{
308 HKEY hkey;308 HKEY hkey;
309 DWORD dwtype, dwsize;309 DWORD dwtype, dwsize;
310 LRESULT lresult;310 LRESULT lresult;
311311
312 DEBUG("GetPPTViewerPath: start\n");312 DEBUG("GetPPTViewerPath: start\n");
313 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS)313 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS)
314 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS)314 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS)
315 return FALSE; 315 return FALSE;
316 dwtype = REG_SZ;316 dwtype = REG_SZ;
317 dwsize = (DWORD)strsize;317 dwsize = (DWORD)strsize;
318 lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype, (LPBYTE)pptviewerpath, &dwsize );318 lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype, (LPBYTE)pptviewerpath, &dwsize );
319 RegCloseKey(hkey);319 RegCloseKey(hkey);
320 if(lresult!=ERROR_SUCCESS)320 if(lresult!=ERROR_SUCCESS)
321 return FALSE;321 return FALSE;
322 pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value322 pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value
323 DEBUG("GetPPTViewerPath: exit ok\n");323 DEBUG("GetPPTViewerPath: exit ok\n");
324 return TRUE;324 return TRUE;
325}325}
326326
327// Unhook the Windows hook 327// Unhook the Windows hook
328void Unhook(int id)328void Unhook(int id)
329{329{
330 DEBUG("Unhook: start %d\n", id);330 DEBUG("Unhook: start %d\n", id);
331 if(pptviewobj[id].hook!=NULL) 331 if(pptviewobj[id].hook!=NULL)
332 UnhookWindowsHookEx(pptviewobj[id].hook);332 UnhookWindowsHookEx(pptviewobj[id].hook);
333 if(pptviewobj[id].mhook!=NULL) 333 if(pptviewobj[id].mhook!=NULL)
334 UnhookWindowsHookEx(pptviewobj[id].mhook);334 UnhookWindowsHookEx(pptviewobj[id].mhook);
335 pptviewobj[id].hook = NULL;335 pptviewobj[id].hook = NULL;
336 pptviewobj[id].mhook = NULL;336 pptviewobj[id].mhook = NULL;
337 DEBUG("Unhook: exit ok\n");337 DEBUG("Unhook: exit ok\n");
338}338}
339339
340// Close the PowerPoint viewer, release resources340// Close the PowerPoint viewer, release resources
341DllExport void ClosePPT(int id)341DllExport void ClosePPT(int id)
342{342{
343 DEBUG("ClosePPT: start%d\n", id);343 DEBUG("ClosePPT: start%d\n", id);
344 pptviewobj[id].state = PPT_CLOSED;344 pptviewobj[id].state = PPT_CLOSED;
345 Unhook(id);345 Unhook(id);
346 if(pptviewobj[id].hWnd==0)346 if(pptviewobj[id].hWnd==0)
347 TerminateThread(pptviewobj[id].hThread, 0);347 TerminateThread(pptviewobj[id].hThread, 0);
348 else348 else
349 PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0);349 PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0);
350 CloseHandle(pptviewobj[id].hThread);350 CloseHandle(pptviewobj[id].hThread);
351 CloseHandle(pptviewobj[id].hProcess);351 CloseHandle(pptviewobj[id].hProcess);
352 memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ));352 memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ));
353 DEBUG("ClosePPT: exit ok\n");353 DEBUG("ClosePPT: exit ok\n");
354 return;354 return;
355}355}
356// Moves the show back onto the display356// Moves the show back onto the display
357DllExport void Resume(int id)357DllExport void Resume(int id)
358{358{
359 DEBUG("Resume: %d\n", id);359 DEBUG("Resume: %d\n", id);
360 MoveWindow(pptviewobj[id].hWnd, pptviewobj[id].rect.left, pptviewobj[id].rect.top, 360 MoveWindow(pptviewobj[id].hWnd, pptviewobj[id].rect.left, pptviewobj[id].rect.top,
361 pptviewobj[id].rect.right - pptviewobj[id].rect.left, 361 pptviewobj[id].rect.right - pptviewobj[id].rect.left,
362 pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE);362 pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE);
363 Unblank(id); 363 Unblank(id);
364}364}
365// Moves the show off the screen so it can't be seen365// Moves the show off the screen so it can't be seen
366DllExport void Stop(int id)366DllExport void Stop(int id)
367{367{
368 DEBUG("Stop:%d\n", id);368 DEBUG("Stop:%d\n", id);
369 MoveWindow(pptviewobj[id].hWnd, -32000, -32000, 369 MoveWindow(pptviewobj[id].hWnd, -32000, -32000,
370 pptviewobj[id].rect.right - pptviewobj[id].rect.left, 370 pptviewobj[id].rect.right - pptviewobj[id].rect.left,
371 pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE);371 pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE);
372}372}
373373
374// Return the total number of slides374// Return the total number of slides
375DllExport int GetSlideCount(int id)375DllExport int GetSlideCount(int id)
376{376{
377 DEBUG("GetSlideCount:%d\n", id);377 DEBUG("GetSlideCount:%d\n", id);
378 if(pptviewobj[id].state==0)378 if(pptviewobj[id].state==0)
379 return -1;379 return -1;
380 else380 else
381 return pptviewobj[id].slideCount;381 return pptviewobj[id].slideCount;
382}382}
383383
384// Return the number of the slide currently viewing384// Return the number of the slide currently viewing
385DllExport int GetCurrentSlide(int id)385DllExport int GetCurrentSlide(int id)
386{386{
387 DEBUG("GetCurrentSlide:%d\n", id);387 DEBUG("GetCurrentSlide:%d\n", id);
388 if(pptviewobj[id].state==0)388 if(pptviewobj[id].state==0)
389 return -1;389 return -1;
390 else390 else
391 return pptviewobj[id].currentSlide;391 return pptviewobj[id].currentSlide;
392}392}
393393
394// Take a step forwards through the show 394// Take a step forwards through the show
395DllExport void NextStep(int id)395DllExport void NextStep(int id)
396{396{
397 DEBUG("NextStep:%d\n", id);397 DEBUG("NextStep:%d\n", id);
398 if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount)398 if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount)
399 return;399 return;
400 PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0);400 PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0);
401}401}
402402
403// Take a step backwards through the show 403// Take a step backwards through the show
404DllExport void PrevStep(int id)404DllExport void PrevStep(int id)
405{405{
406 DEBUG("PrevStep:%d\n", id);406 DEBUG("PrevStep:%d\n", id);
407 PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0);407 PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0);
408}408}
409409
410// Blank the show (black screen)410// Blank the show (black screen)
411DllExport void Blank(int id)411DllExport void Blank(int id)
412{ 412{
413 // B just toggles blank on/off. However pressing any key unblanks.413 // B just toggles blank on/off. However pressing any key unblanks.
414 // So send random unmapped letter first (say 'A'), then we can 414 // So send random unmapped letter first (say 'A'), then we can
415 // better guarantee B will blank instead of trying to guess 415 // better guarantee B will blank instead of trying to guess
416 // whether it was already blank or not.416 // whether it was already blank or not.
417 DEBUG("Blank:%d\n", id);417 DEBUG("Blank:%d\n", id);
418 HWND h1 = GetForegroundWindow();418 HWND h1 = GetForegroundWindow();
419 HWND h2 = GetFocus();419 HWND h2 = GetFocus();
420 SetForegroundWindow(pptviewobj[id].hWnd);420 SetForegroundWindow(pptviewobj[id].hWnd);
421 SetFocus(pptviewobj[id].hWnd);421 SetFocus(pptviewobj[id].hWnd);
422 Sleep(50); // slight pause, otherwise event triggering this call may grab focus back!422 Sleep(50); // slight pause, otherwise event triggering this call may grab focus back!
423 keybd_event((int)'A', 0, 0, 0);423 keybd_event((int)'A', 0, 0, 0);
424 keybd_event((int)'A', 0, KEYEVENTF_KEYUP, 0);424 keybd_event((int)'A', 0, KEYEVENTF_KEYUP, 0);
425 keybd_event((int)'B', 0, 0, 0);425 keybd_event((int)'B', 0, 0, 0);
426 keybd_event((int)'B', 0, KEYEVENTF_KEYUP, 0);426 keybd_event((int)'B', 0, KEYEVENTF_KEYUP, 0);
427 SetForegroundWindow(h1);427 SetForegroundWindow(h1);
428 SetFocus(h2);428 SetFocus(h2);
429 //PostMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'B', 0x00300001);429 //PostMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'B', 0x00300001);
430 //PostMessage(pptviewobj[id].hWnd2, WM_CHAR, 'b', 0x00300001);430 //PostMessage(pptviewobj[id].hWnd2, WM_CHAR, 'b', 0x00300001);
431 //PostMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'B', 0xC0300001);431 //PostMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'B', 0xC0300001);
432}432}
433// Unblank the show 433// Unblank the show
434DllExport void Unblank(int id)434DllExport void Unblank(int id)
435{ 435{
436 DEBUG("Unblank:%d\n", id);436 DEBUG("Unblank:%d\n", id);
437 // Pressing any key resumes. 437 // Pressing any key resumes.
438 // For some reason SendMessage works for unblanking, but not blanking.438 // For some reason SendMessage works for unblanking, but not blanking.
439// SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'A', 0);439// SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'A', 0);
440 SendMessage(pptviewobj[id].hWnd2, WM_CHAR, 'A', 0);440 SendMessage(pptviewobj[id].hWnd2, WM_CHAR, 'A', 0);
441// SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'A', 0);441// SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'A', 0);
442// HWND h1 = GetForegroundWindow();442// HWND h1 = GetForegroundWindow();
443// HWND h2 = GetFocus();443// HWND h2 = GetFocus();
444// Sleep(50); // slight pause, otherwise event triggering this call may grab focus back!444// Sleep(50); // slight pause, otherwise event triggering this call may grab focus back!
445// SetForegroundWindow(pptviewobj[id].hWnd);445// SetForegroundWindow(pptviewobj[id].hWnd);
446// SetFocus(pptviewobj[id].hWnd);446// SetFocus(pptviewobj[id].hWnd);
447// keybd_event((int)'A', 0, 0, 0);447// keybd_event((int)'A', 0, 0, 0);
448// SetForegroundWindow(h1);448// SetForegroundWindow(h1);
449// SetFocus(h2);449// SetFocus(h2);
450}450}
451451
452// Go directly to a slide452// Go directly to a slide
453DllExport void GotoSlide(int id, int slideno)453DllExport void GotoSlide(int id, int slideno)
454{ 454{
455 DEBUG("GotoSlide %i %i:\n", id, slideno);455 DEBUG("GotoSlide %i %i:\n", id, slideno);
456 // Did try WM_KEYDOWN/WM_CHAR/WM_KEYUP with SendMessage but didn't work456 // Did try WM_KEYDOWN/WM_CHAR/WM_KEYUP with SendMessage but didn't work
457 // perhaps I was sending to the wrong window? No idea. 457 // perhaps I was sending to the wrong window? No idea.
458 // Anyway fall back to keybd_event, which is OK as long we makesure458 // Anyway fall back to keybd_event, which is OK as long we makesure
459 // the slideshow has focus first459 // the slideshow has focus first
460 char ch[10];460 char ch[10];
461461
462 if(slideno<0) return;462 if(slideno<0) return;
463 _itoa_s(slideno, ch, 10, 10);463 _itoa_s(slideno, ch, 10, 10);
464 HWND h1 = GetForegroundWindow();464 HWND h1 = GetForegroundWindow();
465 HWND h2 = GetFocus();465 HWND h2 = GetFocus();
466 SetForegroundWindow(pptviewobj[id].hWnd);466 SetForegroundWindow(pptviewobj[id].hWnd);
467 SetFocus(pptviewobj[id].hWnd);467 SetFocus(pptviewobj[id].hWnd);
468 Sleep(50); // slight pause, otherwise event triggering this call may grab focus back!468 Sleep(50); // slight pause, otherwise event triggering this call may grab focus back!
469 for(int i=0;i<10;i++)469 for(int i=0;i<10;i++)
470 {470 {
471 if(ch[i]=='\0') break;471 if(ch[i]=='\0') break;
472 keybd_event((BYTE)ch[i], 0, 0, 0);472 keybd_event((BYTE)ch[i], 0, 0, 0);
473 keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0);473 keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0);
474 }474 }
475 keybd_event(VK_RETURN, 0, 0, 0);475 keybd_event(VK_RETURN, 0, 0, 0);
476 keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);476 keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
477 SetForegroundWindow(h1);477 SetForegroundWindow(h1);
478 SetFocus(h2);478 SetFocus(h2);
479479
480 //for(int i=0;i<10;i++)480 //for(int i=0;i<10;i++)
481 //{481 //{
482 // if(ch[i]=='\0') break;482 // if(ch[i]=='\0') break;
483 // SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, ch[i], 0);483 // SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, ch[i], 0);
484 // SendMessage(pptviewobj[id].hWnd2, WM_CHAR, ch[i], 0);484 // SendMessage(pptviewobj[id].hWnd2, WM_CHAR, ch[i], 0);
485 // SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, ch[i], 0);485 // SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, ch[i], 0);
486 //}486 //}
487 //SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, VK_RETURN, 0);487 //SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, VK_RETURN, 0);
488 //SendMessage(pptviewobj[id].hWnd2, WM_CHAR, VK_RETURN, 0);488 //SendMessage(pptviewobj[id].hWnd2, WM_CHAR, VK_RETURN, 0);
489 //SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, VK_RETURN, 0);489 //SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, VK_RETURN, 0);
490 //keybd_event(VK_RETURN, 0, 0, 0);490 //keybd_event(VK_RETURN, 0, 0, 0);
491}491}
492492
493// Restart the show from the beginning493// Restart the show from the beginning
494DllExport void RestartShow(int id)494DllExport void RestartShow(int id)
495{495{
496 // If we just go direct to slide one, then it remembers that all other slides have496 // If we just go direct to slide one, then it remembers that all other slides have
497 // been animated, so ends up just showing the completed slides of those slides that497 // been animated, so ends up just showing the completed slides of those slides that
498 // have been animated next time we advance. 498 // have been animated next time we advance.
499 // Only way I've found to get around this is to step backwards all the way through. 499 // Only way I've found to get around this is to step backwards all the way through.
500 // Lets move the window out of the way first so the audience doesn't see this.500 // Lets move the window out of the way first so the audience doesn't see this.
501 DEBUG("RestartShow:%d\n", id);501 DEBUG("RestartShow:%d\n", id);
502 Stop(id);502 Stop(id);
503 GotoSlide(id, pptviewobj[id].slideCount);503 GotoSlide(id, pptviewobj[id].slideCount);
504 while(pptviewobj[id].currentSlide>1)504 while(pptviewobj[id].currentSlide>1)
505 {505 {
506 PrevStep(id);506 PrevStep(id);
507 Sleep(10);507 Sleep(10);
508 }508 }
509 for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++)509 for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++)
510 {510 {
511 PrevStep(id);511 PrevStep(id);
512 Sleep(10);512 Sleep(10);
513 }513 }
514 Resume(id);514 Resume(id);
515}515}
516516
517// This hook is started with the PPTVIEW.EXE process and waits for the517// This hook is started with the PPTVIEW.EXE process and waits for the
518// WM_CREATEWND message. At this point (and only this point) can the518// WM_CREATEWND message. At this point (and only this point) can the
519// window be resized to the correct size.519// window be resized to the correct size.
520// Release the hook as soon as we're complete to free up resources520// Release the hook as soon as we're complete to free up resources
521LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam)521LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam)
522{522{
523 HHOOK hook = globalhook;523 HHOOK hook = globalhook;
524 if(nCode==HCBT_CREATEWND)524 if(nCode==HCBT_CREATEWND)
525 {525 {
526 char csClassName[16];526 char csClassName[16];
527 HWND hCurrWnd = (HWND)wParam;527 HWND hCurrWnd = (HWND)wParam;
528 DWORD retProcId = NULL;528 DWORD retProcId = NULL;
529 GetClassName(hCurrWnd, csClassName, sizeof(csClassName));529 GetClassName(hCurrWnd, csClassName, sizeof(csClassName));
530 if((strcmp(csClassName, "paneClassDC")==0)530 if((strcmp(csClassName, "paneClassDC")==0)
531 ||(strcmp(csClassName, "screenClass")==0))531 ||(strcmp(csClassName, "screenClass")==0))
532 {532 {
533 int id=-1;533 int id=-1;
534 DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL);534 DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL);
535 for(int i=0; i<MAX_PPTOBJS; i++)535 for(int i=0; i<MAX_PPTOBJS; i++)
536 {536 {
537 if(pptviewobj[i].dwThreadId==windowthread)537 if(pptviewobj[i].dwThreadId==windowthread)
538 {538 {
539 id=i;539 id=i;
540 break;540 break;
541 }541 }
542 }542 }
543 if(id>=0)543 if(id>=0)
544 {544 {
545 if(strcmp(csClassName, "paneClassDC")==0)545 if(strcmp(csClassName, "paneClassDC")==0)
546 pptviewobj[id].hWnd2=hCurrWnd;546 pptviewobj[id].hWnd2=hCurrWnd;
547 else 547 else
548 {548 {
549 pptviewobj[id].hWnd=hCurrWnd;549 pptviewobj[id].hWnd=hCurrWnd;
550 CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam;550 CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam;
551 if(pptviewobj[id].hParentWnd!=NULL) 551 if(pptviewobj[id].hParentWnd!=NULL)
552 cw->lpcs->hwndParent = pptviewobj[id].hParentWnd;552 cw->lpcs->hwndParent = pptviewobj[id].hParentWnd;
553 cw->lpcs->cy=(pptviewobj[id].rect.bottom-pptviewobj[id].rect.top);553 cw->lpcs->cy=(pptviewobj[id].rect.bottom-pptviewobj[id].rect.top);
554 cw->lpcs->cx=(pptviewobj[id].rect.right-pptviewobj[id].rect.left);554 cw->lpcs->cx=(pptviewobj[id].rect.right-pptviewobj[id].rect.left);
555 cw->lpcs->y=-32000; 555 cw->lpcs->y=-32000;
556 cw->lpcs->x=-32000; 556 cw->lpcs->x=-32000;
557 }557 }
558 if((pptviewobj[id].hWnd!=NULL)&&(pptviewobj[id].hWnd2!=NULL))558 if((pptviewobj[id].hWnd!=NULL)&&(pptviewobj[id].hWnd2!=NULL))
559 {559 {
560 UnhookWindowsHookEx(globalhook);560 UnhookWindowsHookEx(globalhook);
561 globalhook=NULL;561 globalhook=NULL;
562 pptviewobj[id].hook = SetWindowsHookEx(WH_CALLWNDPROC,CwpProc,hInstance,pptviewobj[id].dwThreadId);562 pptviewobj[id].hook = SetWindowsHookEx(WH_CALLWNDPROC,CwpProc,hInstance,pptviewobj[id].dwThreadId);
563 pptviewobj[id].mhook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInstance,pptviewobj[id].dwThreadId);563 pptviewobj[id].mhook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInstance,pptviewobj[id].dwThreadId);
564 Sleep(10);564 Sleep(10);
565 pptviewobj[id].state = PPT_OPENED;565 pptviewobj[id].state = PPT_OPENED;
566 }566 }
567 }567 }
568 }568 }
569 }569 }
570 return CallNextHookEx(hook,nCode,wParam,lParam); 570 return CallNextHookEx(hook,nCode,wParam,lParam);
571}571}
572572
573// This hook exists whilst the slideshow is loading but only listens on the573// This hook exists whilst the slideshow is loading but only listens on the
574// slideshows thread. It listens out for mousewheel events574// slideshows thread. It listens out for mousewheel events
575LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 575LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
576{576{
577 HHOOK hook = NULL;577 HHOOK hook = NULL;
578 MSG *pMSG = (MSG *)lParam;578 MSG *pMSG = (MSG *)lParam;
579 DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd,NULL);579 DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd,NULL);
580 int id=-1;580 int id=-1;
581 for(int i=0; i<MAX_PPTOBJS; i++)581 for(int i=0; i<MAX_PPTOBJS; i++)
582 {582 {
583 if(pptviewobj[i].dwThreadId==windowthread)583 if(pptviewobj[i].dwThreadId==windowthread)
584 {584 {
585 id=i;585 id=i;
586 hook = pptviewobj[id].mhook;586 hook = pptviewobj[id].mhook;
587 break;587 break;
588 }588 }
589 }589 }
590 if(id>=0&&nCode==HC_ACTION&&wParam==PM_REMOVE&&pMSG->message==WM_MOUSEWHEEL)590 if(id>=0&&nCode==HC_ACTION&&wParam==PM_REMOVE&&pMSG->message==WM_MOUSEWHEEL)
591 {591 {
592 if(pptviewobj[id].state!=PPT_LOADED)592 if(pptviewobj[id].state!=PPT_LOADED)
593 {593 {
594 if(pptviewobj[id].currentSlide==1)594 if(pptviewobj[id].currentSlide==1)
595 pptviewobj[id].firstSlideSteps++;595 pptviewobj[id].firstSlideSteps++;
596 pptviewobj[id].steps++;596 pptviewobj[id].steps++;
597 }597 }
598 }598 }
599 return CallNextHookEx(hook, nCode, wParam, lParam);599 return CallNextHookEx(hook, nCode, wParam, lParam);
600}600}
601// This hook exists whilst the slideshow is running but only listens on the601// This hook exists whilst the slideshow is running but only listens on the
602// slideshows thread. It listens out for slide changes, message WM_USER+22.602// slideshows thread. It listens out for slide changes, message WM_USER+22.
603LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){603LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){
604 CWPSTRUCT *cwp;604 CWPSTRUCT *cwp;
605 cwp = (CWPSTRUCT *)lParam;605 cwp = (CWPSTRUCT *)lParam;
606 HHOOK hook = NULL;606 HHOOK hook = NULL;
607 char filename[MAX_PATH];607 char filename[MAX_PATH];
608608
609 DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd,NULL);609 DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd,NULL);
610 int id=-1;610 int id=-1;
611 for(int i=0; i<MAX_PPTOBJS; i++)611 for(int i=0; i<MAX_PPTOBJS; i++)
612 {612 {
613 if(pptviewobj[i].dwThreadId==windowthread)613 if(pptviewobj[i].dwThreadId==windowthread)
614 {614 {
615 id=i;615 id=i;
616 hook = pptviewobj[id].hook;616 hook = pptviewobj[id].hook;
617 break;617 break;
618 }618 }
619 }619 }
620 if((id>=0)&&(nCode==HC_ACTION))620 if((id>=0)&&(nCode==HC_ACTION))
621 {621 {
622 if(cwp->message==WM_USER+22)622 if(cwp->message==WM_USER+22)
623 {623 {
624 if(pptviewobj[id].state != PPT_LOADED)624 if(pptviewobj[id].state != PPT_LOADED)
625 {625 {
626 if((pptviewobj[id].currentSlide>0)626 if((pptviewobj[id].currentSlide>0)
627 && (pptviewobj[id].previewpath!=NULL&&strlen(pptviewobj[id].previewpath)>0))627 && (pptviewobj[id].previewpath!=NULL&&strlen(pptviewobj[id].previewpath)>0))
628 {628 {
629 sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, pptviewobj[id].currentSlide);629 sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, pptviewobj[id].currentSlide);
630 CaptureAndSaveWindow(cwp->hwnd, filename);630 CaptureAndSaveWindow(cwp->hwnd, filename);
631 }631 }
632 }632 }
633 if(cwp->wParam==0)633 if(cwp->wParam==0)
634 {634 {
635 if(pptviewobj[id].currentSlide>0) 635 if(pptviewobj[id].currentSlide>0)
636 {636 {
637 pptviewobj[id].state = PPT_LOADED;637 pptviewobj[id].state = PPT_LOADED;
638 pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1;638 pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1;
639 }639 }
640 } 640 }
641 else641 else
642 {642 {
643 pptviewobj[id].currentSlide = cwp->wParam - 255;643 pptviewobj[id].currentSlide = cwp->wParam - 255;
644 if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount)644 if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount)
645 pptviewobj[id].slideCount = pptviewobj[id].currentSlide;645 pptviewobj[id].slideCount = pptviewobj[id].currentSlide;
646 }646 }
647 }647 }
648 if((pptviewobj[id].state != PPT_CLOSED)&&(cwp->message==WM_CLOSE||cwp->message==WM_QUIT))648 if((pptviewobj[id].state != PPT_CLOSED)&&(cwp->message==WM_CLOSE||cwp->message==WM_QUIT))
649 pptviewobj[id].state = PPT_CLOSING;649 pptviewobj[id].state = PPT_CLOSING;
650 }650 }
651 return CallNextHookEx(hook,nCode,wParam,lParam); 651 return CallNextHookEx(hook,nCode,wParam,lParam);
652}652}
653653
654VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename)654VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename)
655{655{
656 HBITMAP hBmp;656 HBITMAP hBmp;
657 if ((hBmp = CaptureWindow(hWnd)) == NULL) 657 if ((hBmp = CaptureWindow(hWnd)) == NULL)
658 return;658 return;
659659
660 RECT client;660 RECT client;
661 GetClientRect (hWnd, &client);661 GetClientRect (hWnd, &client);
662 UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits662 UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits
663 UINT uiRemainderForPadding;663 UINT uiRemainderForPadding;
664664
665 if ((uiRemainderForPadding = uiBytesPerRow % sizeof (DWORD)) > 0) 665 if ((uiRemainderForPadding = uiBytesPerRow % sizeof (DWORD)) > 0)
666 uiBytesPerRow += (sizeof (DWORD) - uiRemainderForPadding);666 uiBytesPerRow += (sizeof (DWORD) - uiRemainderForPadding);
667667
668 UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom;668 UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom;
669 PBYTE pDataBits;669 PBYTE pDataBits;
670670
671 if ((pDataBits = new BYTE [uiBytesPerAllRows]) != NULL) 671 if ((pDataBits = new BYTE [uiBytesPerAllRows]) != NULL)
672 {672 {
673 BITMAPINFOHEADER bmi = {0};673 BITMAPINFOHEADER bmi = {0};
674 BITMAPFILEHEADER bmf = {0};674 BITMAPFILEHEADER bmf = {0};
675675
676 // Prepare to get the data out of HBITMAP:676 // Prepare to get the data out of HBITMAP:
677 bmi.biSize = sizeof (bmi);677 bmi.biSize = sizeof (bmi);
678 bmi.biPlanes = 1;678 bmi.biPlanes = 1;
679 bmi.biBitCount = 24;679 bmi.biBitCount = 24;
680 bmi.biHeight = client.bottom;680 bmi.biHeight = client.bottom;
681 bmi.biWidth = client.right;681 bmi.biWidth = client.right;
682682
683 // Get it:683 // Get it:
684 HDC hDC = GetDC (hWnd);684 HDC hDC = GetDC (hWnd);
685 GetDIBits (hDC, hBmp, 0, client.bottom, pDataBits, 685 GetDIBits (hDC, hBmp, 0, client.bottom, pDataBits,
686 (BITMAPINFO*) &bmi, DIB_RGB_COLORS);686 (BITMAPINFO*) &bmi, DIB_RGB_COLORS);
687 ReleaseDC (hWnd, hDC);687 ReleaseDC (hWnd, hDC);
688688
689 // Fill the file header:689 // Fill the file header:
690 bmf.bfOffBits = sizeof (bmf) + sizeof (bmi);690 bmf.bfOffBits = sizeof (bmf) + sizeof (bmi);
691 bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows;691 bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows;
692 bmf.bfType = 0x4D42;692 bmf.bfType = 0x4D42;
693693
694 // Writing:694 // Writing:
695 FILE* pFile;695 FILE* pFile;
696 int err = fopen_s(&pFile, filename, "wb");696 int err = fopen_s(&pFile, filename, "wb");
697 if (err == 0) 697 if (err == 0)
698 {698 {
699 fwrite (&bmf, sizeof (bmf), 1, pFile);699 fwrite (&bmf, sizeof (bmf), 1, pFile);
700 fwrite (&bmi, sizeof (bmi), 1, pFile);700 fwrite (&bmi, sizeof (bmi), 1, pFile);
701 fwrite (pDataBits, sizeof (BYTE), uiBytesPerAllRows, pFile);701 fwrite (pDataBits, sizeof (BYTE), uiBytesPerAllRows, pFile);
702 fclose (pFile);702 fclose (pFile);
703 } 703 }
704 delete [] pDataBits;704 delete [] pDataBits;
705 }705 }
706 DeleteObject (hBmp);706 DeleteObject (hBmp);
707}707}
708HBITMAP CaptureWindow (HWND hWnd) {708HBITMAP CaptureWindow (HWND hWnd) {
709 HDC hDC;709 HDC hDC;
710 BOOL bOk = FALSE;710 BOOL bOk = FALSE;
711 HBITMAP hImage = NULL;711 HBITMAP hImage = NULL;
712712
713 hDC = GetDC (hWnd);713 hDC = GetDC (hWnd);
714 RECT rcClient;714 RECT rcClient;
715 GetClientRect (hWnd, &rcClient);715 GetClientRect (hWnd, &rcClient);
716 if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL) 716 if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL)
717 {717 {
718 HDC hMemDC;718 HDC hMemDC;
719 HBITMAP hDCBmp;719 HBITMAP hDCBmp;
720720
721 if ((hMemDC = CreateCompatibleDC (hDC)) != NULL) 721 if ((hMemDC = CreateCompatibleDC (hDC)) != NULL)
722 {722 {
723 hDCBmp = (HBITMAP) SelectObject (hMemDC, hImage);723 hDCBmp = (HBITMAP) SelectObject (hMemDC, hImage);
724 HMODULE hLib = LoadLibrary("User32");724 HMODULE hLib = LoadLibrary("User32");
725 // PrintWindow works for windows outside displayable area725 // PrintWindow works for windows outside displayable area
726 // but was only introduced in WinXP. BitBlt requires the window to be topmost 726 // but was only introduced in WinXP. BitBlt requires the window to be topmost
727 // and within the viewable area of the display727 // and within the viewable area of the display
728 if(GetProcAddress(hLib, "PrintWindow")==NULL)728 if(GetProcAddress(hLib, "PrintWindow")==NULL)
729 {729 {
730 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); 730 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
731 BitBlt (hMemDC, 0, 0, rcClient.right, rcClient.bottom, hDC, 0, 0, SRCCOPY);731 BitBlt (hMemDC, 0, 0, rcClient.right, rcClient.bottom, hDC, 0, 0, SRCCOPY);
732 SetWindowPos(hWnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, SWP_NOSIZE); 732 SetWindowPos(hWnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, SWP_NOSIZE);
733 }733 }
734 else734 else
735 {735 {
736 PrintWindow(hWnd, hMemDC, 0);736 PrintWindow(hWnd, hMemDC, 0);
737 }737 }
738 SelectObject (hMemDC, hDCBmp);738 SelectObject (hMemDC, hDCBmp);
739 DeleteDC (hMemDC);739 DeleteDC (hMemDC);
740 bOk = TRUE;740 bOk = TRUE;
741 }741 }
742 }742 }
743 ReleaseDC (hWnd, hDC);743 ReleaseDC (hWnd, hDC);
744 if (! bOk) 744 if (! bOk)
745 {745 {
746 if (hImage) 746 if (hImage)
747 {747 {
748 DeleteObject (hImage);748 DeleteObject (hImage);
749 hImage = NULL;749 hImage = NULL;
750 }750 }
751 }751 }
752 return hImage;752 return hImage;
753}753}
754754
=== modified file 'openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h'
--- openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h 2008-12-10 20:40:18 +0000
+++ openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h 2009-09-13 15:14:45 +0000
@@ -1,54 +1,54 @@
11
2#define DllExport extern "C" __declspec( dllexport ) 2#define DllExport extern "C" __declspec( dllexport )
33
4enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING};4enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING};
55
6DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);6DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath);
7DllExport void ClosePPT(int id);7DllExport void ClosePPT(int id);
8DllExport int GetCurrentSlide(int id);8DllExport int GetCurrentSlide(int id);
9DllExport int GetSlideCount(int id);9DllExport int GetSlideCount(int id);
10DllExport void NextStep(int id);10DllExport void NextStep(int id);
11DllExport void PrevStep(int id);11DllExport void PrevStep(int id);
12DllExport void GotoSlide(int id, int slideno);12DllExport void GotoSlide(int id, int slideno);
13DllExport void RestartShow(int id);13DllExport void RestartShow(int id);
14DllExport void Blank(int id);14DllExport void Blank(int id);
15DllExport void Unblank(int id);15DllExport void Unblank(int id);
16DllExport void Stop(int id);16DllExport void Stop(int id);
17DllExport void Resume(int id);17DllExport void Resume(int id);
18DllExport void SetDebug(BOOL onoff);18DllExport void SetDebug(BOOL onoff);
1919
20LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam);20LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam);
21LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam);21LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam);
22LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);22LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
23BOOL GetPPTViewerPath(char *pptviewerpath, int strsize);23BOOL GetPPTViewerPath(char *pptviewerpath, int strsize);
24HBITMAP CaptureWindow (HWND hWnd);24HBITMAP CaptureWindow (HWND hWnd);
25VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ;25VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ;
26VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);26VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);
27BOOL GetPPTInfo(int id);27BOOL GetPPTInfo(int id);
28BOOL SavePPTInfo(int id);28BOOL SavePPTInfo(int id);
2929
3030
31void Unhook(int id);31void Unhook(int id);
3232
33#define MAX_PPTOBJS 5033#define MAX_PPTOBJS 50
3434
35struct PPTVIEWOBJ 35struct PPTVIEWOBJ
36{36{
37 HHOOK hook;37 HHOOK hook;
38 HHOOK mhook;38 HHOOK mhook;
39 HWND hWnd;39 HWND hWnd;
40 HWND hWnd2;40 HWND hWnd2;
41 HWND hParentWnd;41 HWND hParentWnd;
42 HANDLE hProcess;42 HANDLE hProcess;
43 HANDLE hThread;43 HANDLE hThread;
44 DWORD dwProcessId;44 DWORD dwProcessId;
45 DWORD dwThreadId;45 DWORD dwThreadId;
46 RECT rect;46 RECT rect;
47 int slideCount;47 int slideCount;
48 int currentSlide;48 int currentSlide;
49 int firstSlideSteps;49 int firstSlideSteps;
50 int steps;50 int steps;
51 char filename[MAX_PATH];51 char filename[MAX_PATH];
52 char previewpath[MAX_PATH];52 char previewpath[MAX_PATH];
53 PPTVIEWSTATE state;53 PPTVIEWSTATE state;
54};54};
55\ No newline at end of file55\ No newline at end of file
5656
=== modified file 'openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj'
--- openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj 2008-12-10 20:40:18 +0000
+++ openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj 2009-09-13 15:14:45 +0000
@@ -1,203 +1,203 @@
1<?xml version="1.0" encoding="Windows-1252"?>1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject2<VisualStudioProject
3 ProjectType="Visual C++"3 ProjectType="Visual C++"
4 Version="9.00"4 Version="9.00"
5 Name="pptviewlib"5 Name="pptviewlib"
6 ProjectGUID="{04CC20D1-DC5A-4189-8181-4011E3C21DCF}"6 ProjectGUID="{04CC20D1-DC5A-4189-8181-4011E3C21DCF}"
7 RootNamespace="pptviewlib"7 RootNamespace="pptviewlib"
8 Keyword="Win32Proj"8 Keyword="Win32Proj"
9 TargetFrameworkVersion="196613"9 TargetFrameworkVersion="196613"
10 >10 >
11 <Platforms>11 <Platforms>
12 <Platform12 <Platform
13 Name="Win32"13 Name="Win32"
14 />14 />
15 </Platforms>15 </Platforms>
16 <ToolFiles>16 <ToolFiles>
17 </ToolFiles>17 </ToolFiles>
18 <Configurations>18 <Configurations>
19 <Configuration19 <Configuration
20 Name="Debug|Win32"20 Name="Debug|Win32"
21 OutputDirectory="$(SolutionDir)$(ConfigurationName)"21 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
22 IntermediateDirectory="$(ConfigurationName)"22 IntermediateDirectory="$(ConfigurationName)"
23 ConfigurationType="2"23 ConfigurationType="2"
24 CharacterSet="2"24 CharacterSet="2"
25 >25 >
26 <Tool26 <Tool
27 Name="VCPreBuildEventTool"27 Name="VCPreBuildEventTool"
28 />28 />
29 <Tool29 <Tool
30 Name="VCCustomBuildTool"30 Name="VCCustomBuildTool"
31 />31 />
32 <Tool32 <Tool
33 Name="VCXMLDataGeneratorTool"33 Name="VCXMLDataGeneratorTool"
34 />34 />
35 <Tool35 <Tool
36 Name="VCWebServiceProxyGeneratorTool"36 Name="VCWebServiceProxyGeneratorTool"
37 />37 />
38 <Tool38 <Tool
39 Name="VCMIDLTool"39 Name="VCMIDLTool"
40 />40 />
41 <Tool41 <Tool
42 Name="VCCLCompilerTool"42 Name="VCCLCompilerTool"
43 Optimization="0"43 Optimization="0"
44 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS"44 PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS"
45 MinimalRebuild="true"45 MinimalRebuild="true"
46 BasicRuntimeChecks="3"46 BasicRuntimeChecks="3"
47 RuntimeLibrary="3"47 RuntimeLibrary="3"
48 UsePrecompiledHeader="0"48 UsePrecompiledHeader="0"
49 WarningLevel="3"49 WarningLevel="3"
50 DebugInformationFormat="4"50 DebugInformationFormat="4"
51 />51 />
52 <Tool52 <Tool
53 Name="VCManagedResourceCompilerTool"53 Name="VCManagedResourceCompilerTool"
54 />54 />
55 <Tool55 <Tool
56 Name="VCResourceCompilerTool"56 Name="VCResourceCompilerTool"
57 />57 />
58 <Tool58 <Tool
59 Name="VCPreLinkEventTool"59 Name="VCPreLinkEventTool"
60 />60 />
61 <Tool61 <Tool
62 Name="VCLinkerTool"62 Name="VCLinkerTool"
63 LinkIncremental="2"63 LinkIncremental="2"
64 ModuleDefinitionFile=""64 ModuleDefinitionFile=""
65 GenerateDebugInformation="true"65 GenerateDebugInformation="true"
66 SubSystem="2"66 SubSystem="2"
67 TargetMachine="1"67 TargetMachine="1"
68 />68 />
69 <Tool69 <Tool
70 Name="VCALinkTool"70 Name="VCALinkTool"
71 />71 />
72 <Tool72 <Tool
73 Name="VCManifestTool"73 Name="VCManifestTool"
74 />74 />
75 <Tool75 <Tool
76 Name="VCXDCMakeTool"76 Name="VCXDCMakeTool"
77 />77 />
78 <Tool78 <Tool
79 Name="VCBscMakeTool"79 Name="VCBscMakeTool"
80 />80 />
81 <Tool81 <Tool
82 Name="VCFxCopTool"82 Name="VCFxCopTool"
83 />83 />
84 <Tool84 <Tool
85 Name="VCAppVerifierTool"85 Name="VCAppVerifierTool"
86 />86 />
87 <Tool87 <Tool
88 Name="VCPostBuildEventTool"88 Name="VCPostBuildEventTool"
89 />89 />
90 </Configuration>90 </Configuration>
91 <Configuration91 <Configuration
92 Name="Release|Win32"92 Name="Release|Win32"
93 OutputDirectory="$(SolutionDir)$(ConfigurationName)"93 OutputDirectory="$(SolutionDir)$(ConfigurationName)"
94 IntermediateDirectory="$(ConfigurationName)"94 IntermediateDirectory="$(ConfigurationName)"
95 ConfigurationType="2"95 ConfigurationType="2"
96 CharacterSet="1"96 CharacterSet="1"
97 WholeProgramOptimization="1"97 WholeProgramOptimization="1"
98 >98 >
99 <Tool99 <Tool
100 Name="VCPreBuildEventTool"100 Name="VCPreBuildEventTool"
101 />101 />
102 <Tool102 <Tool
103 Name="VCCustomBuildTool"103 Name="VCCustomBuildTool"
104 />104 />
105 <Tool105 <Tool
106 Name="VCXMLDataGeneratorTool"106 Name="VCXMLDataGeneratorTool"
107 />107 />
108 <Tool108 <Tool
109 Name="VCWebServiceProxyGeneratorTool"109 Name="VCWebServiceProxyGeneratorTool"
110 />110 />
111 <Tool111 <Tool
112 Name="VCMIDLTool"112 Name="VCMIDLTool"
113 />113 />
114 <Tool114 <Tool
115 Name="VCCLCompilerTool"115 Name="VCCLCompilerTool"
116 Optimization="2"116 Optimization="2"
117 EnableIntrinsicFunctions="true"117 EnableIntrinsicFunctions="true"
118 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS"118 PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS"
119 RuntimeLibrary="2"119 RuntimeLibrary="2"
120 EnableFunctionLevelLinking="true"120 EnableFunctionLevelLinking="true"
121 UsePrecompiledHeader="2"121 UsePrecompiledHeader="2"
122 WarningLevel="3"122 WarningLevel="3"
123 DebugInformationFormat="3"123 DebugInformationFormat="3"
124 />124 />
125 <Tool125 <Tool
126 Name="VCManagedResourceCompilerTool"126 Name="VCManagedResourceCompilerTool"
127 />127 />
128 <Tool128 <Tool
129 Name="VCResourceCompilerTool"129 Name="VCResourceCompilerTool"
130 />130 />
131 <Tool131 <Tool
132 Name="VCPreLinkEventTool"132 Name="VCPreLinkEventTool"
133 />133 />
134 <Tool134 <Tool
135 Name="VCLinkerTool"135 Name="VCLinkerTool"
136 LinkIncremental="1"136 LinkIncremental="1"
137 ModuleDefinitionFile="pptviewlib.def"137 ModuleDefinitionFile="pptviewlib.def"
138 GenerateDebugInformation="true"138 GenerateDebugInformation="true"
139 SubSystem="2"139 SubSystem="2"
140 OptimizeReferences="2"140 OptimizeReferences="2"
141 EnableCOMDATFolding="2"141 EnableCOMDATFolding="2"
142 TargetMachine="1"142 TargetMachine="1"
143 />143 />
144 <Tool144 <Tool
145 Name="VCALinkTool"145 Name="VCALinkTool"
146 />146 />
147 <Tool147 <Tool
148 Name="VCManifestTool"148 Name="VCManifestTool"
149 />149 />
150 <Tool150 <Tool
151 Name="VCXDCMakeTool"151 Name="VCXDCMakeTool"
152 />152 />
153 <Tool153 <Tool
154 Name="VCBscMakeTool"154 Name="VCBscMakeTool"
155 />155 />
156 <Tool156 <Tool
157 Name="VCFxCopTool"157 Name="VCFxCopTool"
158 />158 />
159 <Tool159 <Tool
160 Name="VCAppVerifierTool"160 Name="VCAppVerifierTool"
161 />161 />
162 <Tool162 <Tool
163 Name="VCPostBuildEventTool"163 Name="VCPostBuildEventTool"
164 />164 />
165 </Configuration>165 </Configuration>
166 </Configurations>166 </Configurations>
167 <References>167 <References>
168 </References>168 </References>
169 <Files>169 <Files>
170 <Filter170 <Filter
171 Name="Source Files"171 Name="Source Files"
172 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"172 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
173 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"173 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
174 >174 >
175 <File175 <File
176 RelativePath=".\pptviewlib.cpp"176 RelativePath=".\pptviewlib.cpp"
177 >177 >
178 </File>178 </File>
179 <File179 <File
180 RelativePath=".\README.TXT"180 RelativePath=".\README.TXT"
181 >181 >
182 </File>182 </File>
183 </Filter>183 </Filter>
184 <Filter184 <Filter
185 Name="Header Files"185 Name="Header Files"
186 Filter="h;hpp;hxx;hm;inl;inc;xsd"186 Filter="h;hpp;hxx;hm;inl;inc;xsd"
187 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"187 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
188 >188 >
189 <File189 <File
190 RelativePath=".\pptviewlib.h"190 RelativePath=".\pptviewlib.h"
191 >191 >
192 </File>192 </File>
193 </Filter>193 </Filter>
194 <Filter194 <Filter
195 Name="Resource Files"195 Name="Resource Files"
196 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"196 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
197 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"197 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
198 >198 >
199 </Filter>199 </Filter>
200 </Files>200 </Files>
201 <Globals>201 <Globals>
202 </Globals>202 </Globals>
203</VisualStudioProject>203</VisualStudioProject>
The diff has been truncated for viewing.