Wittyshare  0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
WsImages2.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2006-Today Guy Deleeuw
3 *
4 * See the LICENSE file for terms of use.
5 */
6 
7 #include <dlfcn.h>
8 #include <stdio.h>
9 
10 #include <iostream>
11 #include <fstream>
12 
13 #include <boost/algorithm/string/replace.hpp>
14 #include <boost/lexical_cast.hpp>
15 #include <boost/filesystem/operations.hpp>
16 #include <boost/filesystem/exception.hpp>
17 
18 #include <gdcore/gdCore.h>
19 
20 #include <Wt/WLogger>
21 #include <Wt/WImage>
22 #include <Wt/WBoostAny>
23 #include <Wt/WText>
24 #include <Wt/WTheme>
25 
26 #include <gdcore/gdImage.h>
27 
28 #include <Main/WsApplication.h>
29 #include <User/WsUser.h>
30 
31 #include "WsImages2.h"
32 
33 using namespace Wt;
34 
35 wsi2Anchor::wsi2Anchor(const Wt::WLink& link, const Wt::WString& text, Wt::WContainerWidget* parent)
36  : WAnchor(link, text, parent), m_nImageIndex(0)
37 {
38  clicked().connect(SLOT(this, wsi2Anchor::doClicked));
39 }
40 
41 void wsi2Anchor::setImageIndex(int imageIndex)
42 {
43  m_nImageIndex = imageIndex;
44 }
45 
46 void wsi2Anchor::doClicked(Wt::WMouseEvent mEv)
47 {
49 }
50 
51 Wt::Signal<int>& wsi2Anchor::imageSelected()
52 {
53  return m_sigImageSelected;
54 };
55 
56 
57 
58 
59 
60 
61 
62 WsImages2::WsImages2(WContainerWidget* parent)
63  : WContainerWidget(parent), m_bDebug(false), m_lDelay(5000), m_nCurrentImage(0), m_pTimer(0), m_bLoaded(false), m_bOnLoad(false)
64 {
65  if ( WString::tr("byObjectStyleSheet").narrow() == "true" )
66  wApp->useStyleSheet(wApp->theme()->resourcesUrl() + "wittyshare/Css/WsImages2.css");
67  addStyleClass("WsImages2Widget");
68 }
69 
71 {
72  if ( m_pTimer ) {
73  m_pTimer->stop();
74  delete m_pTimer;
75  }
76 }
77 
79 {
80  WContainerWidget::load();
81  if ( !m_bLoaded )
82  build();
84  wApp->internalPathChanged().connect(SLOT(this, WsImages2::doPathChanged));
85  loadImage();
86  if ( m_bReactWhenPathChange ) return;
87  if ( !m_lDelay ) return;
88  if ( m_sImagesVect.size() < 2 ) return;
89  // On ajoute le timer au widget, les objets de ce type ne sont pas détruits par un clear();
90  m_pTimer = new WTimer();
91  m_pTimer->setInterval(m_lDelay);
92  m_pTimer->start();
93  m_pTimer->timeout().connect(SLOT(this, WsImages2::doTimeout));
94 }
95 
97 {
98  long lDelay = asNumber(option("image_delay"));
99  if ( lDelay > 0 )
100  m_lDelay = lDelay;
101  if ( asString(option("reactWhenPathChange")) == "false" )
102  m_bReactWhenPathChange = false;
103  std::string sImagesPath = asString(option("imagesPath")).toUTF8();
104  if ( sImagesPath.size() < 1 )
105  sImagesPath = wApp->theme()->resourcesUrl() + "wittyshare/Images/WsImages2";
106  if ( boost::filesystem::is_directory(WsApp->docRoot() + sImagesPath) ) {
107  boost::filesystem::directory_iterator end_itr;
108  try {
109  for (boost::filesystem::directory_iterator itr_dir(WsApp->docRoot() + sImagesPath); itr_dir != end_itr; ++itr_dir) {
110  if ( ! ( itr_dir->path().extension() == ".jpeg"
111  || itr_dir->path().extension() == ".jpg"
112  || itr_dir->path().extension() == ".png"
113  ) ) continue;
114  if ( gdcore_isPathHidden(itr_dir->path()) ) continue;
115  if ( gdcore_isPathSymLink(itr_dir->path()) ) continue;
116  if ( boost::filesystem::is_directory(itr_dir->status()) ) continue;
117  boost::filesystem::path newPath = itr_dir->path();
118  m_sImagesVect.push_back(newPath.string());
119  }
120  } catch (boost::filesystem::filesystem_error& e) {
121  wApp->log("ERROR") << "WsImages2::build() bad image path =" << sImagesPath << " error = " << e.what();
122  return;
123  }
124  } else
125  m_sImagesVect.push_back(WsApp->docRoot() + sImagesPath);
126  // TODO : the images in vect is img3 img2 img1, not sure that the sort apply on all cases
127  std::sort(m_sImagesVect.begin(), m_sImagesVect.end());
128  for (int iP = 0; iP < m_sImagesVect.size(); ++iP) {
129  // Load the internalPath from a file with an extension url, the name of the file does be the same that the image.
130  std::string sLink;
131  std::string sLinkType;
132  std::string sTitle;
133  std::string sShortDescription;
134  boost::filesystem::path urlFile(m_sImagesVect[iP]);
135  urlFile.replace_extension(".url");
136  if ( boost::filesystem::exists(urlFile) ) {
137  std::ifstream f(urlFile.string().c_str());
138  std::string sLine;
139  // std::getline(f, sLine) Line without cr
140  while ( std::getline(f, sLine) ) {
141  if ( sLine.compare(0, 5, "link=") == 0 ) sLink = sLine;
142  if ( sLine.compare(0, 9, "linkType=") == 0 ) sLinkType = sLine;
143  if ( sLine.compare(0, 6, "title=") == 0 ) sTitle = sLine;
144  if ( sLine.compare(0, 17, "shortDescription=") == 0 ) sShortDescription = sLine;
145  }
146  boost::algorithm::replace_all(sLink, "link=", "");
147  boost::algorithm::replace_all(sLinkType, "linkType=", "");
148  boost::algorithm::replace_all(sTitle, "title=", "");
149  boost::algorithm::replace_all(sShortDescription, "shortDescription=", "");
150  }
151  m_sImagesLink.push_back(sLink);
152  m_sImagesLinkType.push_back(sLinkType);
153  if ( m_bDebug )
154  wApp->log("notice") << "WsImages2::build() url image = " << sLink;
155  // Load the short description of the internalPath loaded from the url file.
156  if ( sShortDescription.size() < 1 )
157  if ( sLink.size() > 0 ) {
158  WsUser* pUser = WsApp->wsUser();
159  NodePtr pNode = pUser->getAccessRoot().get()->eatPath(sLink);
160  if ( pNode ) {
161  sShortDescription = pNode.get()->getProperties().get()->get("global", "short_description", "");
162  if ( sTitle.size() < 1 )
163  sTitle = pNode.get()->getDisplayName(true);
164  }
165  }
166  m_sImagesTitle.push_back(sTitle);
167  m_sImagesText.push_back(sShortDescription);
168  }
169  m_bLoaded = true;
170 }
171 
173 {
174  return m_sImagesVect.size();
175 }
176 
178 {
179  if ( m_bOnLoad ) return;
180  if ( (m_nCurrentImage + 1) >= m_sImagesVect.size() ) m_nCurrentImage = 0;
181  else ++m_nCurrentImage;
182  loadImage();
183 }
184 
186 {
187  doTimeout();
188 }
189 
191 {
192  if ( m_bOnLoad ) return;
193  m_bOnLoad = true;
194  if ( !m_sImagesVect.size() ) {
195  WApplication::instance()->log("notice") << "WsImages2::loadImage() : no images !";
196  m_bOnLoad = false;
197  return;
198  }
199  clear();
200  if ( asString(option("useImageTitle")) == "true" ) {
201  std::string curImgTitle(m_sImagesTitle[m_nCurrentImage]);
202  if ( curImgTitle.size() > 0 ) {
203  boost::algorithm::replace_all(curImgTitle, "&", "&amp;");
204  WText* pTextTitle = new WText(curImgTitle);
205  pTextTitle->addStyleClass("WsImage2Title");
206  addWidget(pTextTitle);
207  }
208  }
209  WContainerWidget* cwImg = new WContainerWidget();
210  cwImg->addStyleClass("WsImages2");
211  if ( m_sImagesVect.size() > 1 && asString(option("useCountImages")) != "false") {
212  WContainerWidget* cw = new WContainerWidget();
213  cw->addStyleClass("countImages");
214  for (int countImage = 0; countImage < m_sImagesVect.size(); ++countImage) {
215  wsi2Anchor* pAnchor = 0;
216  if ( asString(option("setImagesCount")) != "true" )
217  pAnchor = new wsi2Anchor(WLink(), "&nbsp;");
218  else
219  pAnchor = new wsi2Anchor(WLink(), asString(countImage + 1));
220  pAnchor->imageSelected().connect(SLOT(this, WsImages2::doCounterClicked));
221  pAnchor->setImageIndex(countImage);
222  if ( countImage == m_nCurrentImage )
223  pAnchor->addStyleClass("selected");
224  cw->addWidget(pAnchor);
225  }
226  cwImg->addWidget(cw);
227  }
228  std::string curImgUrl(m_sImagesVect[m_nCurrentImage]);
229  gdImageProperties imgProp = gdImage_size(curImgUrl);
230  boost::algorithm::replace_first(curImgUrl, wApp->docRoot(), "");
231  WLink myLink(WLink::Url, curImgUrl);
232  if ( asString(option("imageInBackground")) == "true" ) {
233  cwImg->decorationStyle().setBackgroundImage(myLink, Wt::WCssDecorationStyle::NoRepeat);
234  if ( asString(option("textWidget")) == "true" ) {
235  if ( m_sImagesText[m_nCurrentImage].size() > 0 ) {
236  WText* textImage = new WText(m_sImagesText[m_nCurrentImage]);
237  textImage->addStyleClass("WsImages2Text");
238  if ( m_sImagesLink[m_nCurrentImage].size() > 1 ) {
239  boost::filesystem::path pUrl(m_sImagesLink[m_nCurrentImage]);
240  if ( pUrl.extension() != ".nolink" ) {
241  textImage->addStyleClass("WsClickable");
242  textImage->clicked().connect(SLOT(this, WsImages2::doImageClicked));
243  }
244  }
245  cwImg->addWidget(textImage);
246  }
247  }
248  } else {
249  WImage* pImage = new WImage();
250  pImage->setImageLink(myLink);
251  cwImg->addWidget(pImage);
252  }
253  if ( asString(option("plusWidget")) == "true" ) {
254  std::string curImgUrl2(m_sImagesLink[m_nCurrentImage]);
255  WAnchor* pA = new WAnchor(WLink(WLink::InternalPath, curImgUrl2), "+");
256  pA->addStyleClass("WsPlusWidget");
257  cwImg->addWidget(pA);
258  }
259  cwImg->resize(WLength(imgProp.width, WLength::Pixel), WLength(imgProp.height, WLength::Pixel));
260  addWidget(cwImg);
261  // TODO : test if needed
262  refresh();
263  m_bOnLoad = false;
264 }
265 
266 const std::string& WsImages2::text()
267 {
269 }
270 
272 {
273  wApp->setInternalPath(m_sImagesLink[m_nCurrentImage], true);
274 }
275 
277 {
278  if ( m_bOnLoad ) return;
279  m_nCurrentImage = index;
280  loadImage();
281 }
282 
std::vector< std::string > m_sImagesVect
Definition: WsImages2.h:92
boost::shared_ptr< WsAbstractNode > NodePtr
bool m_bOnLoad
Definition: WsImages2.h:98
void loadImage()
Load the image with the current index.
Definition: WsImages2.cpp:190
void setImageIndex(int imageIndex)
Definition: WsImages2.cpp:41
void build()
Build the vector.
Definition: WsImages2.cpp:96
virtual void load()
Load the widget (traditional wt virtual function).
Definition: WsImages2.cpp:78
long m_lDelay
Definition: WsImages2.h:89
WsImages2(Wt::WContainerWidget *parent=0)
CTor.
Definition: WsImages2.cpp:62
Wt::Signal< int > & imageSelected()
Definition: WsImages2.cpp:51
wsi2Anchor(const Wt::WLink &link, const Wt::WString &text, Wt::WContainerWidget *parent=0)
Definition: WsImages2.cpp:35
Interface that provides differents methods for accessing the FsTree as well as other features...
Definition: WsUser.h:33
int count()
Return the number of images.
Definition: WsImages2.cpp:172
std::vector< std::string > m_sImagesTitle
Definition: WsImages2.h:96
void doClicked(Wt::WMouseEvent mEv)
Definition: WsImages2.cpp:46
void doCounterClicked(int index)
Definition: WsImages2.cpp:276
bool m_bLoaded
Definition: WsImages2.h:90
const boost::any & option(const std::string &attribute) const
Get an options value.
Definition: WsOption.cpp:62
std::vector< std::string > m_sImagesLink
Definition: WsImages2.h:94
void doTimeout()
Definition: WsImages2.cpp:177
int m_nImageIndex
Definition: WsImages2.h:30
std::vector< std::string > m_sImagesText
Definition: WsImages2.h:93
Wt::WTimer * m_pTimer
Definition: WsImages2.h:100
~WsImages2()
DTor.
Definition: WsImages2.cpp:70
void doPathChanged()
Definition: WsImages2.cpp:185
#define WsApp
Define a shortcut to the application instance.
Definition: WsApplication.h:62
bool m_bReactWhenPathChange
Definition: WsImages2.h:88
int m_nCurrentImage
Definition: WsImages2.h:99
const std::string & text()
Return the text of the current image.
Definition: WsImages2.cpp:266
NodePtr getAccessRoot()
return the root node of the access tree starting from the root
Definition: WsUser.cpp:50
bool m_bDebug
Definition: WsImages2.h:87
Wt::Signal< int > m_sigImageSelected
Definition: WsImages2.h:29
User class.
std::vector< std::string > m_sImagesLinkType
Definition: WsImages2.h:95
void doImageClicked()
Definition: WsImages2.cpp:271
a wittyShare class that render images randomly