1 /*
2  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
3  *
4  * See the LICENSE file for terms of use.
5  */
6 #include "Wt/WApplication.h"
7 #include "Wt/WLabel.h"
8 #include "Wt/WText.h"
9 #include "Wt/WImage.h"
10 #include "Wt/WFormWidget.h"
11 
12 #include "DomElement.h"
13 
14 namespace Wt {
15 
WLabel()16 WLabel::WLabel()
17   : buddyChanged_(false),
18     newImage_(false),
19     newText_(false)
20 { }
21 
WLabel(const WString & text)22 WLabel::WLabel(const WString& text)
23   : buddyChanged_(false),
24     newImage_(false),
25     newText_(false)
26 {
27   auto wtext = std::make_unique<WText>(text);
28   manageWidget(text_, std::move(wtext));
29   text_->setWordWrap(false);
30 }
31 
WLabel(std::unique_ptr<WImage> image)32 WLabel::WLabel(std::unique_ptr<WImage> image)
33   : buddyChanged_(false),
34     newImage_(false),
35     newText_(false)
36 {
37   manageWidget(image_, std::move(image));
38 }
39 
~WLabel()40 WLabel::~WLabel()
41 {
42   beingDeleted();
43   manageWidget(text_, std::unique_ptr<WText>());
44   manageWidget(image_, std::unique_ptr<WImage>());
45   setBuddy(nullptr);
46 }
47 
buddy()48 WFormWidget *WLabel::buddy() const
49 {
50   return buddy_.get();
51 }
52 
setBuddy(WFormWidget * buddy)53 void WLabel::setBuddy(WFormWidget *buddy)
54 {
55   if (buddy_)
56     buddy_->setLabel(nullptr);
57 
58   buddy_ = buddy;
59   if (buddy_)
60     buddy_->setLabel(this);
61 
62   buddyChanged_ = true;
63   repaint();
64 }
65 
setText(const WString & text)66 void WLabel::setText(const WString& text)
67 {
68   if (this->text() == text)
69     return;
70 
71   if (!text_) {
72     auto wtext = std::make_unique<WText>(text);
73     manageWidget(text_, std::move(wtext));
74     text_->setWordWrap(false);
75     newText_ = true;
76     repaint(RepaintFlag::SizeAffected);
77   }
78 
79   text_->setText(text);
80 }
81 
setTextFormat(TextFormat format)82 bool WLabel::setTextFormat(TextFormat format)
83 {
84   if (!text_) {
85     setText("A"); setText("");
86   }
87 
88   return text_->setTextFormat(format);
89 }
90 
textFormat()91 TextFormat WLabel::textFormat() const
92 {
93   if (!text_)
94     return TextFormat::XHTML;
95   else
96     return text_->textFormat();
97 }
98 
text()99 WString WLabel::text() const
100 {
101   if (text_)
102     return text_->text();
103   else
104     return WString::Empty;
105 }
106 
setImage(std::unique_ptr<WImage> image,Side side)107 void WLabel::setImage(std::unique_ptr<WImage> image, Side side)
108 {
109   manageWidget(image_, std::move(image));
110   imageSide_ = side;
111   newImage_ = true;
112   repaint(RepaintFlag::SizeAffected);
113 }
114 
setWordWrap(bool wordWrap)115 void WLabel::setWordWrap(bool wordWrap)
116 {
117  if (!text_) {
118     setText("A"); setText("");
119   }
120 
121   text_->setWordWrap(wordWrap);
122 }
123 
wordWrap()124 bool WLabel::wordWrap() const
125 {
126   return text_ ? text_->wordWrap() : false;
127 }
128 
updateDom(DomElement & element,bool all)129 void WLabel::updateDom(DomElement& element, bool all)
130 {
131   WApplication *app = WApplication::instance();
132 
133   if (image_ && text_)
134     if (imageSide_ == Side::Left) {
135       updateImage(element, all, app, 0);
136       updateText(element, all, app, 1);
137     } else {
138       updateText(element, all, app, 0);
139       updateImage(element, all, app, 1);
140     }
141   else {
142     updateText(element, all, app, 0);
143     updateImage(element, all, app, 0);
144   }
145 
146   if (buddyChanged_ || all) {
147     if (buddy_)
148       element.setAttribute("for", buddy_->formName());
149     buddyChanged_ = false;
150   }
151 
152   WInteractWidget::updateDom(element, all);
153 }
154 
updateImage(DomElement & element,bool all,WApplication * app,int pos)155 void WLabel::updateImage(DomElement& element, bool all, WApplication *app,
156 			 int pos)
157 {
158   if (newImage_ || all) {
159     if (image_)
160       element.insertChildAt(image_->createSDomElement(app), pos);
161     newImage_ = false;
162   }
163 }
164 
updateText(DomElement & element,bool all,WApplication * app,int pos)165 void WLabel::updateText(DomElement& element, bool all, WApplication *app,
166 			int pos)
167 {
168   if (newText_ || all) {
169     if (text_)
170       element.insertChildAt(text_->createSDomElement(app), pos);
171     newText_ = false;
172   }
173 }
174 
propagateSetEnabled(bool enabled)175 void WLabel::propagateSetEnabled(bool enabled)
176 {
177   if (text_)
178     text_->propagateSetEnabled(enabled);
179 
180   WInteractWidget::propagateSetEnabled(enabled);
181 }
182 
propagateRenderOk(bool deep)183 void WLabel::propagateRenderOk(bool deep)
184 {
185   newImage_ = false;
186   newText_ = false;
187   buddyChanged_ = false;
188 
189   WInteractWidget::propagateRenderOk(deep);
190 }
191 
domElementType()192 DomElementType WLabel::domElementType() const
193 {
194   // The label in <a><label /></a> eats an onclick event in IE
195   // We should explicitly continue to propagate the onclick event ?
196   // For now we avoid to create a LABEL element if no buddy is set
197   // (This is used e.g. in WTreeView)
198   if (buddy_)
199     return DomElementType::LABEL;
200   else
201     return isInline() ? DomElementType::SPAN : DomElementType::DIV;
202 }
203 
getDomChanges(std::vector<DomElement * > & result,WApplication * app)204 void WLabel::getDomChanges(std::vector<DomElement *>& result,
205 			   WApplication *app)
206 {
207   WInteractWidget::getDomChanges(result, app);
208 
209   if (text_)
210     text_->getDomChanges(result, app);
211   if (image_)
212     image_->getDomChanges(result, app);
213 }
214 
iterateChildren(const HandleWidgetMethod & method)215 void WLabel::iterateChildren(const HandleWidgetMethod &method) const
216 {
217   if (text_)
218 #ifndef WT_TARGET_JAVA
219     method(text_.get());
220 #else
221     method.handle(text_.get());
222 #endif
223   if (image_)
224 #ifndef WT_TARGET_JAVA
225     method(image_.get());
226 #else
227     method.handle(image_.get());
228 #endif
229 }
230 
231 }
232