1 /*
2 * Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
3 *
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.
8 *
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.
13 *
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
17 * 02110-1301, USA.
18 */
19
20 #include <stdlib.h>
21
22 #include <ZLApplication.h>
23 #include <ZLFile.h>
24 #include <ZLXMLReader.h>
25 #include <ZLResource.h>
26 #include <ZLibrary.h>
27 #include <ZLPopupData.h>
28 #include "ZLToolbar.h"
29 #include "ZLApplicationWindow.h"
30
31 #include <optionEntries/ZLStringInfoEntry.h>
32
33 class ZLToolbarCreator : public ZLXMLReader {
34
35 public:
36 ZLToolbarCreator(ZLToolbar &toolbar);
37 void startElementHandler(const char *tag, const char **attributes);
38
39 private:
40 ZLToolbar &myToolbar;
41 };
42
createToolbar(int index)43 void ZLApplication::createToolbar(int index) {
44 toolbar(index);
45 std::string fileName = ZLibrary::DefaultFilesPathPrefix();
46 const bool isWindowToolbar = index == ZLApplicationWindow::WINDOW_TOOLBAR;
47 fileName += isWindowToolbar ? "toolbar.xml" : "fullscreen_toolbar.xml";
48 ZLToolbarCreator(isWindowToolbar ? *myToolbar : *myFullscreenToolbar).readDocument(ZLFile(fileName));
49 }
50
toolbar(int index) const51 const ZLToolbar &ZLApplication::toolbar(int index) const {
52 if (index == ZLApplicationWindow::WINDOW_TOOLBAR) {
53 if (myToolbar.isNull()) {
54 myToolbar = new ZLToolbar();
55 }
56 return *myToolbar;
57 } else {
58 if (myFullscreenToolbar.isNull()) {
59 myFullscreenToolbar = new ZLToolbar();
60 }
61 return *myFullscreenToolbar;
62 }
63 }
64
registerPopupData(const std::string & actionId,shared_ptr<ZLPopupData> popupData)65 void ZLApplication::registerPopupData(const std::string &actionId, shared_ptr<ZLPopupData> popupData) {
66 toolbar(ZLApplicationWindow::WINDOW_TOOLBAR);
67 myToolbar->registerPopupData(actionId, popupData);
68 }
69
registerPopupData(const std::string & actionId,shared_ptr<ZLPopupData> popupData)70 void ZLToolbar::registerPopupData(const std::string &actionId, shared_ptr<ZLPopupData> popupData) {
71 myPopupDataMap[actionId] = popupData;
72 }
73
ZLToolbarCreator(ZLToolbar & toolbar)74 ZLToolbarCreator::ZLToolbarCreator(ZLToolbar &toolbar) : myToolbar(toolbar) {
75 }
76
startElementHandler(const char * tag,const char ** attributes)77 void ZLToolbarCreator::startElementHandler(const char *tag, const char **attributes) {
78 static const std::string BUTTON = "button";
79 static const std::string MENU_BUTTON = "menuButton";
80 static const std::string TOGGLE_BUTTON = "toggleButton";
81 static const std::string TEXT_FIELD = "textField";
82 static const std::string COMBO_BOX = "comboBox";
83 static const std::string SEARCH_FIELD = "searchField";
84 static const std::string SEPARATOR = "separator";
85 static const std::string FILL_SEPARATOR = "fillSeparator";
86
87 const char *id = attributeValue(attributes, "id");
88
89 if (SEPARATOR == tag) {
90 new ZLToolbar::SeparatorItem(myToolbar, ZLToolbar::Item::SEPARATOR);
91 } else if (FILL_SEPARATOR == tag) {
92 new ZLToolbar::SeparatorItem(myToolbar, ZLToolbar::Item::FILL_SEPARATOR);
93 } else if (id == 0) {
94 return;
95 } else if (BUTTON == tag) {
96 new ZLToolbar::PlainButtonItem(myToolbar, id);
97 } else if (MENU_BUTTON == tag) {
98 new ZLToolbar::MenuButtonItem(myToolbar, id);
99 } else if (TOGGLE_BUTTON == tag) {
100 const char *groupId = attributeValue(attributes, "group");
101 const char *isDefault = attributeValue(attributes, "default");
102 if (groupId != 0) {
103 ZLToolbar::ButtonGroup &group = myToolbar.getButtonGroup(groupId);
104 ZLToolbar::ToggleButtonItem *button = new ZLToolbar::ToggleButtonItem(myToolbar, id, group);
105 if (isDefault != 0) {
106 group.setDefaultAction(id);
107 }
108 if (group.defaultAction() == id) {
109 button->press();
110 }
111 }
112 } else if (TEXT_FIELD == tag || COMBO_BOX == tag || SEARCH_FIELD == tag) {
113 const char *parameterId = attributeValue(attributes, "parameterId");
114 const char *maxWidth = attributeValue(attributes, "maxWidth");
115 if (parameterId != 0 && maxWidth != 0) {
116 int nMaxWidth = atoi(maxWidth);
117 if (nMaxWidth > 0) {
118 ZLToolbar::Item::Type type = ZLToolbar::Item::TEXT_FIELD;
119 if (COMBO_BOX == tag) {
120 type = ZLToolbar::Item::COMBO_BOX;
121 } else if (SEARCH_FIELD == tag) {
122 type = ZLToolbar::Item::SEARCH_FIELD;
123 }
124 ZLToolbar::ParameterItem *item = new ZLToolbar::ParameterItem(
125 myToolbar, type, id, parameterId, nMaxWidth
126 );
127 const char *symbolSet = attributeValue(attributes, "symbols");
128 if (symbolSet != 0 && std::string(symbolSet) == "digits") {
129 item->setSymbolSet(ZLToolbar::ParameterItem::SET_DIGITS);
130 }
131 }
132 }
133 }
134 }
135
items() const136 const ZLToolbar::ItemVector &ZLToolbar::items() const {
137 return myItems;
138 }
139
resource(const std::string & id)140 const ZLResource &ZLToolbar::resource(const std::string &id) {
141 return ZLResource::resource("toolbar")[id];
142 }
143
Item(ZLToolbar & toolbar,Type type)144 ZLToolbar::Item::Item(ZLToolbar &toolbar, Type type) : myToolbar(toolbar), myType(type) {
145 toolbar.myItems.push_back(this);
146 }
147
~Item()148 ZLToolbar::Item::~Item() {
149 }
150
toolbar() const151 const ZLToolbar &ZLToolbar::Item::toolbar() const {
152 return myToolbar;
153 }
154
type() const155 ZLToolbar::Item::Type ZLToolbar::Item::type() const {
156 return myType;
157 }
158
ActionItem(ZLToolbar & toolbar,Type type,const std::string & actionId)159 ZLToolbar::ActionItem::ActionItem(ZLToolbar &toolbar, Type type, const std::string &actionId) :
160 Item(toolbar, type), myActionId(actionId), myResource(toolbar.resource(actionId)) {
161 }
162
actionId() const163 const std::string &ZLToolbar::ActionItem::actionId() const {
164 return myActionId;
165 }
166
label() const167 const std::string &ZLToolbar::ActionItem::label() const {
168 const ZLResource &labelResource = myResource["label"];
169 if (!labelResource.hasValue()) {
170 static const std::string EMPTY;
171 return EMPTY;
172 }
173 return labelResource.value();
174 }
175
tooltip() const176 const std::string &ZLToolbar::ActionItem::tooltip() const {
177 const ZLResource &tooltipResource = myResource["tooltip"];
178 if (!tooltipResource.hasValue()) {
179 static const std::string EMPTY;
180 return EMPTY;
181 }
182 return tooltipResource.value();
183 }
184
AbstractButtonItem(ZLToolbar & toolbar,Type type,const std::string & actionId)185 ZLToolbar::AbstractButtonItem::AbstractButtonItem(ZLToolbar &toolbar, Type type, const std::string &actionId) : ActionItem(toolbar, type, actionId) {
186 }
187
PlainButtonItem(ZLToolbar & toolbar,const std::string & actionId)188 ZLToolbar::PlainButtonItem::PlainButtonItem(ZLToolbar &toolbar, const std::string &actionId) :
189 AbstractButtonItem(toolbar, PLAIN_BUTTON, actionId) {
190 }
191
MenuButtonItem(ZLToolbar & toolbar,const std::string & actionId)192 ZLToolbar::MenuButtonItem::MenuButtonItem(ZLToolbar &toolbar, const std::string &actionId) :
193 AbstractButtonItem(toolbar, MENU_BUTTON, actionId) {
194 }
195
popupTooltip() const196 const std::string &ZLToolbar::MenuButtonItem::popupTooltip() const {
197 const ZLResource &popupResource = myResource["popup"];
198 if (!popupResource.hasValue()) {
199 static const std::string EMPTY;
200 return EMPTY;
201 }
202 return popupResource.value();
203 }
204
popupData() const205 shared_ptr<ZLPopupData> ZLToolbar::MenuButtonItem::popupData() const {
206 std::map<std::string,shared_ptr<ZLPopupData> >::const_iterator it =
207 toolbar().myPopupDataMap.find(actionId());
208 return (it == toolbar().myPopupDataMap.end()) ? 0 : it->second;
209 }
210
ToggleButtonItem(ZLToolbar & toolbar,const std::string & actionId,ButtonGroup & group)211 ZLToolbar::ToggleButtonItem::ToggleButtonItem(ZLToolbar &toolbar, const std::string &actionId, ButtonGroup &group) : AbstractButtonItem(toolbar, TOGGLE_BUTTON, actionId), myGroup(group) {
212 myGroup.myItems.insert(this);
213 }
214
iconName() const215 const std::string &ZLToolbar::AbstractButtonItem::iconName() const {
216 return actionId();
217 }
218
buttonGroup()219 ZLToolbar::ButtonGroup &ZLToolbar::ToggleButtonItem::buttonGroup() {
220 return myGroup;
221 }
222
press()223 void ZLToolbar::ToggleButtonItem::press() {
224 myGroup.press(this);
225 }
226
isPressed() const227 bool ZLToolbar::ToggleButtonItem::isPressed() const {
228 return this == myGroup.myPressedItem;
229 }
230
getButtonGroup(const std::string & id)231 ZLToolbar::ButtonGroup &ZLToolbar::getButtonGroup(const std::string &id) {
232 shared_ptr<ButtonGroup> group = myButtonGroups[id];
233 if (group.isNull()) {
234 group = new ButtonGroup(id);
235 myButtonGroups[id] = group;
236 }
237 return *group;
238 }
239
ZLToolbar()240 ZLToolbar::ZLToolbar() {
241 }
242
ButtonGroup(const std::string & groupId)243 ZLToolbar::ButtonGroup::ButtonGroup(const std::string &groupId) : myPressedItem(0), myDefaultButtonOption(ZLCategoryKey::LOOK_AND_FEEL, "ToggleButtonGroup", groupId, "") {
244 }
245
press(const ToggleButtonItem * item)246 void ZLToolbar::ButtonGroup::press(const ToggleButtonItem *item) {
247 myPressedItem = item;
248 myDefaultButtonOption.setValue(item->actionId());
249 }
250
setDefaultAction(const std::string & actionId)251 void ZLToolbar::ButtonGroup::setDefaultAction(const std::string &actionId) {
252 if (myDefaultButtonOption.value().empty()) {
253 myDefaultButtonOption.setValue(actionId);
254 }
255 }
256
defaultAction() const257 const std::string &ZLToolbar::ButtonGroup::defaultAction() const {
258 return myDefaultButtonOption.value();
259 }
260
SeparatorItem(ZLToolbar & toolbar,Type type)261 ZLToolbar::SeparatorItem::SeparatorItem(ZLToolbar &toolbar, Type type) : Item(toolbar, type) {
262 }
263
ParameterItem(ZLToolbar & toolbar,Type type,const std::string & actionId,const std::string & parameterId,int maxWidth)264 ZLToolbar::ParameterItem::ParameterItem(ZLToolbar &toolbar, Type type, const std::string &actionId, const std::string ¶meterId, int maxWidth) :
265 ActionItem(toolbar, type, actionId),
266 myParameterId(parameterId),
267 myMaxWidth(maxWidth),
268 mySymbolSet(SET_ANY) {
269 }
270
parameterId() const271 const std::string &ZLToolbar::ParameterItem::parameterId() const {
272 return myParameterId;
273 }
274
maxWidth() const275 int ZLToolbar::ParameterItem::maxWidth() const {
276 return myMaxWidth;
277 }
278
symbolSet() const279 ZLToolbar::ParameterItem::SymbolSet ZLToolbar::ParameterItem::symbolSet() const {
280 return mySymbolSet;
281 }
282
setSymbolSet(SymbolSet symbolSet)283 void ZLToolbar::ParameterItem::setSymbolSet(SymbolSet symbolSet) {
284 mySymbolSet = symbolSet;
285 }
286
resource(const std::string & actionId)287 const ZLResource &ZLPopupData::resource(const std::string &actionId) {
288 return ZLToolbar::resource(actionId);
289 }
290