Wt examples 3.3.12
SourceView.C
Go to the documentation of this file.
1#include "SourceView.h"
2
3#include <iostream>
4#include <fstream>
5#include <sstream>
6
7#include <stdlib.h>
8
9#include <boost/algorithm/string.hpp>
10#include <boost/filesystem/operations.hpp>
11#include <boost/filesystem/convenience.hpp>
12
13#include <Wt/WApplication>
14#include <Wt/WText>
15#include <Wt/WImage>
16
17using namespace Wt;
18namespace fs = boost::filesystem;
19
20SourceView::SourceView(int fileNameRole, int contentRole, int filePathRole)
21 : fileNameRole_(fileNameRole),
22 contentRole_(contentRole),
23 filePathRole_(filePathRole),
24 imageResource_(0)
25{}
26
29
31{
32 if (index != index_ && index.isValid()) {
33 std::string fp = index.data(filePathRole_).empty() ? std::string()
34 : boost::any_cast<std::string>(index.data(filePathRole_));
35
36 if (!index.data(contentRole_).empty()
37 || (!fp.empty() && !fs::is_directory(fp))) {
38 index_ = index;
39 update();
40
41 return true;
42 }
43 }
44
45 return false;
46}
47
48std::string tempFileName()
49{
50#ifndef WT_WIN32
51 char spool[20];
52 strcpy(spool, "/tmp/wtXXXXXX");
53
54 int i = mkstemp(spool);
55 close(i);
56#else
57 char spool[2 * L_tmpnam];
58 tmpnam(spool);
59#endif
60 return std::string(spool);
61}
62
63std::string getLanguageFromFileExtension(const std::string &fileName)
64{
65 if (boost::iends_with(fileName, ".h")
66 || boost::iends_with(fileName, ".C")
67 || boost::iends_with(fileName, ".cpp"))
68 return "cpp";
69 else if (boost::iends_with(fileName, ".xml"))
70 return "xml";
71 else if (boost::iends_with(fileName, ".html"))
72 return "html";
73 else if (boost::iends_with(fileName, ".java"))
74 return "java";
75 else if (boost::iends_with(fileName, ".js"))
76 return "javascript";
77 else if (boost::iends_with(fileName, ".css"))
78 return "css";
79 else
80 return std::string();
81}
82
83std::string readFileToString(const std::string& fileName)
84{
85 std::size_t outputFileSize = (std::size_t)fs::file_size(fileName);
86 std::fstream file (fileName.c_str(), std::ios::in | std::ios::binary);
87 char* memblock = new char [outputFileSize];
88 file.read(memblock, (std::streamsize)outputFileSize);
89 file.close();
90 std::string data = std::string(memblock, outputFileSize);
91 delete [] memblock;
92 return data;
93}
94
96{
97 if (!index_.isValid()) {
98 // no content
99 WText *result = new WText();
100 result->setInline(false);
101 return result;
102 }
103
104 /*
105 * read the contents, from string or file name
106 */
107 boost::any contentsData = index_.data(contentRole_);
108 std::string content;
109 if (!contentsData.empty())
110 content = boost::any_cast<const std::string&>(contentsData);
111 boost::any fileNameData = index_.data(fileNameRole_);
112 std::string fileName =
113 boost::any_cast<const std::string&>(fileNameData);
114 boost::any filePathData = index_.data(filePathRole_);
115 std::string filePath;
116 if (!filePathData.empty())
117 filePath = boost::any_cast<const std::string&>(filePathData);
118
119 /*
120 * determine source language, for source highlight
121 */
122 std::string lang = getLanguageFromFileExtension(fileName);
123 if (content != "" && content.substr(0, 100).find("-*- C++ -*-")
124 != std::string::npos)
125 lang = "cpp";
126
127 std::string outputFileName;
128
129 if (lang != "") {
130 std::string inputFileName;
131
132 if (!filePathData.empty())
133 inputFileName = filePath;
134 else {
135 inputFileName = tempFileName();
136 std::ofstream out(inputFileName.c_str(),
137 std::ios::out | std::ios::binary);
138 out.write(content.c_str(), (std::streamsize)content.length());
139 out.close();
140 }
141
142 outputFileName = tempFileName();
143
144 std::string sourceHighlightCommand = "source-highlight ";
145 sourceHighlightCommand += "--src-lang=" + lang + " ";
146 sourceHighlightCommand += "--out-format=xhtml ";
147 sourceHighlightCommand += "--input=" + inputFileName + " ";
148 sourceHighlightCommand += "--output=" + outputFileName + " ";
149
150 std::cerr << sourceHighlightCommand << std::endl;
151 bool sourceHighlightOk = system(sourceHighlightCommand.c_str()) == 0;
152
153 if (sourceHighlightOk)
154 content = readFileToString(outputFileName);
155 else {
156 content = readFileToString(inputFileName);
157 lang = "";
158 }
159 unlink(outputFileName.c_str());
160
161 if (filePathData.empty())
162 unlink(inputFileName.c_str());
163 }
164
165 if (content == "")
166 // do not load binary files, we would need to perform proper UTF-8
167 // transcoding to display them
168 if (!boost::iends_with(fileName, ".jar")
169 && !boost::iends_with(fileName, ".war")
170 && !boost::iends_with(fileName, ".class"))
171 content = readFileToString(fileName);
172
173 delete imageResource_;
174 imageResource_ = 0;
175
176 WWidget *result = 0;
177
178 if (!imageExtension(fileName).empty()) {
179 WImage *image = new WImage();
181 imageResource_->setMimeType("mime/" + imageExtension(fileName));
182 imageResource_->setData((const unsigned char*)content.data(),
183 (int)content.length());
185 result = image;
186 } else if (lang != "") {
187 WText *text = new WText();
189 text->setText(WString::fromUTF8(content));
190 result = text;
191 } else {
192 WText *text = new WText();
194 text->setText(WString::fromUTF8(content));
195 result = text;
196 }
197
198 result->setInline(false);
199 WApplication::instance()
200 ->doJavaScript(result->jsRef() + ".parentNode.scrollTop = 0;");
201 return result;
202}
203
204std::string SourceView::imageExtension(const std::string& fileName)
205{
206 static const char *imageExtensions[] = {
207 ".png", ".gif", ".jpg", "jpeg", ".ico", 0
208 };
209
210 fs::path p(fileName);
211 std::string extension = fs::extension(p);
212
213 for (const char **s = imageExtensions; *s != 0; ++s)
214 if (*s == extension)
215 return extension.substr(1);
216
217 return std::string();
218}
std::string readFileToString(const std::string &fileName)
Definition SourceView.C:83
std::string getLanguageFromFileExtension(const std::string &fileName)
Definition SourceView.C:63
std::string tempFileName()
Definition SourceView.C:48
bool setIndex(const Wt::WModelIndex &index)
Sets the model index.
Definition SourceView.C:30
std::string imageExtension(const std::string &fileName)
Definition SourceView.C:204
int fileNameRole_
The role that is currently displayed.
Definition SourceView.h:60
Wt::WModelIndex index_
The index that is currently displayed.
Definition SourceView.h:57
virtual Wt::WWidget * renderView()
Returns the widget that renders the view.
Definition SourceView.C:95
int contentRole_
Definition SourceView.h:61
SourceView(int fileNameRole, int contentRole, int filePathRole)
Constructor.
Definition SourceView.C:20
int filePathRole_
Definition SourceView.h:62
Wt::WMemoryResource * imageResource_
Definition SourceView.h:64
virtual ~SourceView()
Destructor.
Definition SourceView.C:27
void setImageLink(const WLink &link)
void setMimeType(const std::string &mimeType)
void setData(const std::vector< unsigned char > &data)
bool isValid() const
boost::any data(int role=DisplayRole) const
static WString fromUTF8(const std::string &value, bool checkValid=false)
bool setText(const WString &text)
bool setTextFormat(TextFormat format)
virtual void setInline(bool isInline)
std::string jsRef() const
virtual void setInline(bool inlined)=0
PlainText
XHTMLUnsafeText

Generated on Fri May 17 2024 for the C++ Web Toolkit (Wt) by doxygen 1.9.8