2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include <ZLOptionsDialog.h>
21 #include <ZLApplication.h>
23 #include <optionEntries/ZLSimpleOptionEntry.h>
24 #include <optionEntries/ZLSimpleKeyOptionEntry.h>
26 #include "KeyBindingsPage.h"
28 #include "../fbreader/FBReader.h"
29 #include "../fbreader/FBReaderActions.h"
31 class KeyboardControlEntry
: public ZLSimpleBooleanOptionEntry
{
34 KeyboardControlEntry(FBReader
&fbreader
);
35 void onStateChanged(bool state
);
41 KeyboardControlEntry::KeyboardControlEntry(FBReader
&fbreader
) : ZLSimpleBooleanOptionEntry(fbreader
.KeyboardControlOption
), myFBReader(fbreader
) {
44 void KeyboardControlEntry::onStateChanged(bool state
) {
45 ZLSimpleBooleanOptionEntry::onStateChanged(state
);
46 myFBReader
.grabAllKeys(state
);
49 class SingleKeyOptionEntry
: public ZLSimpleKeyOptionEntry
{
52 SingleKeyOptionEntry(const CodeIndexBimap
&bimap
, ZLKeyBindings
&bindings
);
53 const CodeIndexBimap
&codeIndexBimap() const;
56 const CodeIndexBimap
&myBimap
;
59 SingleKeyOptionEntry::SingleKeyOptionEntry(const CodeIndexBimap
&bimap
, ZLKeyBindings
&bindings
) : ZLSimpleKeyOptionEntry(bindings
), myBimap(bimap
) {
62 const ZLSimpleKeyOptionEntry::CodeIndexBimap
&SingleKeyOptionEntry::codeIndexBimap() const {
66 class MultiKeyOptionEntry
: public ZLKeyOptionEntry
{
69 MultiKeyOptionEntry(const ZLResource
&resource
, FBReader
&fbreader
);
71 int actionIndex(const std::string
&key
);
72 void onValueChanged(const std::string
&key
, int index
);
73 void onKeySelected(const std::string
&key
);
75 void setOrientation(ZLViewWidget::Angle
);
76 void setExitOnCancelEntry(ZLOptionEntry
*exitOnCancelEntry
);
79 void addAction(const std::string
&actionId
);
82 const ZLResource
&myResource
;
83 ZLSimpleKeyOptionEntry::CodeIndexBimap myBimap
;
85 SingleKeyOptionEntry myEntry0
;
86 SingleKeyOptionEntry myEntry90
;
87 SingleKeyOptionEntry myEntry180
;
88 SingleKeyOptionEntry myEntry270
;
89 SingleKeyOptionEntry
*myCurrentEntry
;
90 ZLOptionEntry
*myExitOnCancelEntry
;
93 void MultiKeyOptionEntry::addAction(const std::string
&actionId
) {
94 myBimap
.insert(actionId
);
95 addActionName(myResource
[ZLResourceKey(actionId
)].value());
98 MultiKeyOptionEntry::MultiKeyOptionEntry(const ZLResource
&resource
, FBReader
&fbreader
) :
100 myResource(resource
),
101 myEntry0(myBimap
, fbreader
.keyBindings(ZLViewWidget::DEGREES0
)),
102 myEntry90(myBimap
, fbreader
.keyBindings(ZLViewWidget::DEGREES90
)),
103 myEntry180(myBimap
, fbreader
.keyBindings(ZLViewWidget::DEGREES180
)),
104 myEntry270(myBimap
, fbreader
.keyBindings(ZLViewWidget::DEGREES270
)),
105 myCurrentEntry(&myEntry0
),
106 myExitOnCancelEntry(0) {
107 addAction(ZLApplication::NoAction
);
110 addAction(ActionCode::SHOW_COLLECTION
);
111 addAction(ActionCode::SHOW_LAST_BOOKS
);
112 addAction(ActionCode::OPEN_PREVIOUS_BOOK
);
113 addAction(ActionCode::SHOW_CONTENTS
);
116 addAction(ActionCode::SCROLL_TO_HOME
);
117 addAction(ActionCode::SCROLL_TO_START_OF_TEXT
);
118 addAction(ActionCode::SCROLL_TO_END_OF_TEXT
);
119 addAction(ActionCode::GOTO_NEXT_TOC_SECTION
);
120 addAction(ActionCode::GOTO_PREVIOUS_TOC_SECTION
);
121 addAction(ActionCode::LARGE_SCROLL_FORWARD
);
122 addAction(ActionCode::LARGE_SCROLL_BACKWARD
);
123 addAction(ActionCode::SMALL_SCROLL_FORWARD
);
124 addAction(ActionCode::SMALL_SCROLL_BACKWARD
);
125 addAction(ActionCode::UNDO
);
126 addAction(ActionCode::REDO
);
129 addAction(ActionCode::COPY_SELECTED_TEXT_TO_CLIPBOARD
);
130 addAction(ActionCode::OPEN_SELECTED_TEXT_IN_DICTIONARY
);
131 addAction(ActionCode::CLEAR_SELECTION
);
134 addAction(ActionCode::SEARCH
);
135 addAction(ActionCode::FIND_PREVIOUS
);
136 addAction(ActionCode::FIND_NEXT
);
139 addAction(ActionCode::INCREASE_FONT
);
140 addAction(ActionCode::DECREASE_FONT
);
141 addAction(ActionCode::SHOW_HIDE_POSITION_INDICATOR
);
142 addAction(ActionCode::TOGGLE_FULLSCREEN
);
143 addAction(ActionCode::FULLSCREEN_ON
);
144 addAction(ActionCode::ROTATE_SCREEN
);
147 addAction(ActionCode::SHOW_OPTIONS
);
148 addAction(ActionCode::SHOW_BOOK_INFO
);
149 addAction(ActionCode::ADD_BOOK
);
152 addAction(ActionCode::CANCEL
);
153 addAction(ActionCode::QUIT
);
156 void MultiKeyOptionEntry::setOrientation(ZLViewWidget::Angle angle
) {
158 case ZLViewWidget::DEGREES0
:
159 myCurrentEntry
= &myEntry0
;
161 case ZLViewWidget::DEGREES90
:
162 myCurrentEntry
= &myEntry90
;
164 case ZLViewWidget::DEGREES180
:
165 myCurrentEntry
= &myEntry180
;
167 case ZLViewWidget::DEGREES270
:
168 myCurrentEntry
= &myEntry270
;
174 void MultiKeyOptionEntry::onAccept() {
176 myEntry90
.onAccept();
177 myEntry180
.onAccept();
178 myEntry270
.onAccept();
181 int MultiKeyOptionEntry::actionIndex(const std::string
&key
) {
182 return myCurrentEntry
->actionIndex(key
);
185 void MultiKeyOptionEntry::onValueChanged(const std::string
&key
, int index
) {
186 myCurrentEntry
->onValueChanged(key
, index
);
187 if (myExitOnCancelEntry
!= 0) {
188 myExitOnCancelEntry
->setVisible(myBimap
.codeByIndex(index
) == ActionCode::CANCEL
);
192 void MultiKeyOptionEntry::setExitOnCancelEntry(ZLOptionEntry
*exitOnCancelEntry
) {
193 myExitOnCancelEntry
= exitOnCancelEntry
;
196 void MultiKeyOptionEntry::onKeySelected(const std::string
&key
) {
197 if (myExitOnCancelEntry
!= 0) {
198 myExitOnCancelEntry
->setVisible(myBimap
.codeByIndex(myCurrentEntry
->actionIndex(key
)) == ActionCode::CANCEL
);
202 class OrientationEntry
: public ZLComboOptionEntry
{
205 OrientationEntry(MultiKeyOptionEntry
&keyEntry
);
206 const std::string
&initialValue() const;
207 const std::vector
<std::string
> &values() const;
208 void onValueSelected(int index
);
209 void onAccept(const std::string
&value
);
212 MultiKeyOptionEntry
&myKeyEntry
;
215 OrientationEntry::OrientationEntry(MultiKeyOptionEntry
&keyEntry
) : myKeyEntry(keyEntry
) {
218 const std::string
&OrientationEntry::initialValue() const {
222 const std::vector
<std::string
> &OrientationEntry::values() const {
223 static std::vector
<std::string
> _values
;
224 if (_values
.empty()) {
225 _values
.push_back("0 Degrees");
226 _values
.push_back("90 Degrees Counterclockwise");
227 _values
.push_back("180 Degrees");
228 _values
.push_back("90 Degrees Clockwise");
233 void OrientationEntry::onValueSelected(int index
) {
234 static ZLViewWidget::Angle angles
[] = {
235 ZLViewWidget::DEGREES0
,
236 ZLViewWidget::DEGREES90
,
237 ZLViewWidget::DEGREES180
,
238 ZLViewWidget::DEGREES270
240 myKeyEntry
.setOrientation(angles
[index
]);
243 void OrientationEntry::onAccept(const std::string
&) {
246 class UseSeparateOptionsEntry
: public ZLSimpleBooleanOptionEntry
{
249 UseSeparateOptionsEntry(FBReader
&fbreader
, ZLOptionEntry
&keyEntry
, OrientationEntry
&orientationEntry
);
250 void onStateChanged(bool state
);
253 ZLOptionEntry
&myKeyEntry
;
254 OrientationEntry
&myOrientationEntry
;
257 UseSeparateOptionsEntry::UseSeparateOptionsEntry(FBReader
&fbreader
, ZLOptionEntry
&keyEntry
, OrientationEntry
&orientationEntry
) : ZLSimpleBooleanOptionEntry(fbreader
.UseSeparateBindingsOption
), myKeyEntry(keyEntry
), myOrientationEntry(orientationEntry
) {
260 void UseSeparateOptionsEntry::onStateChanged(bool state
) {
261 ZLSimpleBooleanOptionEntry::onStateChanged(state
);
262 myOrientationEntry
.setVisible(state
);
263 myKeyEntry
.resetView();
266 KeyBindingsPage::KeyBindingsPage(FBReader
&fbreader
, ZLDialogContent
&dialogTab
) {
267 if (ZLBooleanOption(ZLCategoryKey::EMPTY
, ZLOption::PLATFORM_GROUP
, ZLOption::FULL_KEYBOARD_CONTROL
, false).value()) {
268 dialogTab
.addOption(ZLResourceKey("grabSystemKeys"), new KeyboardControlEntry(fbreader
));
270 ZLResourceKey
actionKey("action");
271 MultiKeyOptionEntry
*keyEntry
= new MultiKeyOptionEntry(dialogTab
.resource(actionKey
), fbreader
);
272 OrientationEntry
*orientationEntry
= new OrientationEntry(*keyEntry
);
273 ZLBooleanOptionEntry
*useSeparateBindingsEntry
= new UseSeparateOptionsEntry(fbreader
, *keyEntry
, *orientationEntry
);
274 dialogTab
.addOption(ZLResourceKey("separate"), useSeparateBindingsEntry
);
275 dialogTab
.addOption(ZLResourceKey("orientation"), orientationEntry
);
276 dialogTab
.addOption("", "", keyEntry
);
277 ZLOptionEntry
*exitOnCancelEntry
= new ZLSimpleBooleanOptionEntry(fbreader
.QuitOnCancelOption
);
278 keyEntry
->setExitOnCancelEntry(exitOnCancelEntry
);
279 dialogTab
.addOption(ZLResourceKey("quitOnCancel"), exitOnCancelEntry
);
280 exitOnCancelEntry
->setVisible(false);
281 useSeparateBindingsEntry
->onStateChanged(useSeparateBindingsEntry
->initialState());