/usr/include/Wt/WFileUpload is in libwt-dev 3.3.6+dfsg-1.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | // This may look like C code, but it's really -*- C++ -*-
/*
* Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
#ifndef WFILEUPLOAD_H_
#define WFILEUPLOAD_H_
#include <Wt/WWebWidget>
namespace Wt {
/*! \class WFileUpload Wt/WFileUpload Wt/WFileUpload
* \brief A widget that allows a file to be uploaded.
*
* This widget is displayed as a box in which a filename can be
* entered and a browse button.
*
* Depending on availability of JavaScript, the behaviour of the widget
* is different, but the API is designed in a way which facilitates
* a portable use.
*
* When JavaScript is available, the file will not be uploaded until
* upload() is called. This will start an asynchronous upload (and
* thus return immediately). \if cpp While the file is being uploaded,
* the dataReceived() signal is emitted when data is being received
* and if the connector library provides support (see also
* WResource::setUploadProgress() for a more detailed
* discussion). Although you can modify the GUI from this signal, you
* still need to have a mechanism in place to update the client
* interface (using a WTimer or using \link
* WApplication::enableUpdates() server-push\endlink). When the file
* has been uploaded, the uploaded() signal is emitted, or if the file
* was too large, the fileTooLarge() signal is emitted. You may
* configure a progress bar that is used to show the upload progress
* using setProgressBar(). \endif
*
* When no JavaScript is available, the file will be uploaded with the
* next click event. Thus, upload() has no effect -- the file will
* already be uploaded, and the corresponding signals will already be
* emitted. To test if upload() will start an upload, you may check
* using the canUpload() call.
*
* Thus, to properly use the widget, one needs to follow these
* rules:
* <ul>
* <li>Be prepared to handle the uploaded() or fileTooLarge() signals
* also when upload() was not called.</li>
* <li>Check using canUpload() if upload() will schedule a new
* upload. if (!canUpload()) then upload() will not have any
* effect. if (canUpload()), upload() will start a new file upload,
* which completes succesfully using an uploaded() signal or a
* fileTooLarge() signals gets emitted.
* </li>
* </ul>
*
* The %WFileUpload widget must be hidden or deleted when a file is
* received. In addition it is wise to prevent the user from uploading
* the file twice as in the example below.
*
* The uploaded file is automatically spooled to a local temporary
* file which will be deleted together with the WFileUpload widget,
* unless stealSpooledFile() is called.
*
* \if cpp
* Usage example:
* \code
* Wt::WFileUpload *upload = new Wt::WFileUpload(this);
* upload->setFileTextSize(40);
*
* // Provide a button
* Wt::WPushButton *uploadButton = new Wt::WPushButton("Send", this);
* // Upload when the button is clicked.
* uploadButton->clicked().connect(upload, &Wt::WFileUpload::upload);
* uploadButton->clicked().connect(uploadButton, &Wt::WPushButton::disable);
*
* // Upload automatically when the user entered a file.
* upload->changed().connect(upload, &WFileUpload::upload);
* upload->changed().connect(uploadButton, &Wt::WPushButton::disable);
*
* // React to a succesfull upload.
* upload->uploaded().connect(this, &MyWidget::fileUploaded);
*
* // React to a fileupload problem.
* upload->fileTooLarge().connect(this, &MyWidget::fileTooLarge);
* \endcode
* \endif
*
* %WFileUpload is an \link WWidget::setInline(bool) inline \endlink widget.
*
* <h3>CSS</h3>
*
* The file upload itself corresponds to a <tt><input
* type="file"></tt> tag, but may be wrapped in a
* <tt><form></tt> tag for an Ajax session to implement the
* asynchronous upload action. This widget does not provide styling,
* and styling through CSS is not well supported across browsers.
*/
class WT_API WFileUpload : public WWebWidget
{
public:
/*! \brief Creates a file upload widget
*/
WFileUpload(WContainerWidget *parent = 0);
~WFileUpload();
/*! \brief Sets whether the file upload accepts multiple files.
*
* In browsers which support the "multiple" attribute for the file
* upload (to be part of HTML5) control, this will allow the user to
* select multiple files at once.
*
* All uploaded files are available from uploadedFiles(). The
* single-file API will return only information on the first
* uploaded file.
*
* The default value is \c false.
*/
void setMultiple(bool multiple);
/*! \brief Returns whether multiple files can be uploaded.
*
* \sa setMultiple()
*/
bool multiple() const { return flags_.test(BIT_MULTIPLE); }
/*! \brief Sets the size of the file input.
*/
void setFileTextSize(int chars);
/*! \brief Returns the size of the file input.
*/
int fileTextSize() const { return textSize_; }
/*! \brief Returns the spooled location of the uploaded file.
*
* Returns the temporary filename in which the uploaded file was
* spooled. The file is guaranteed to exist as long as the
* WFileUpload widget is not deleted, or a new file is not uploaded.
*
* When multiple files were uploaded, this returns the information
* from the first file.
*
* \sa stealSpooledFile()
* \sa uploaded
*/
std::string spoolFileName() const;
/*! \brief Returns the client filename.
*
* When multiple files were uploaded, this returns the information
* from the first file.
*/
WT_USTRING clientFileName() const;
/*! \brief Returns the client content description.
*
* When multiple files were uploaded, this returns the information
* from the first file.
*/
WT_USTRING contentDescription() const;
/*! \brief Steals the spooled file.
*
* By stealing the file, the spooled file will no longer be deleted
* together with this widget, which means you need to take care of
* managing that.
*
* When multiple files were uploaded, this returns the information
* from the first file.
*/
void stealSpooledFile();
/*! \brief Returns whether one or more files have been uploaded.
*/
bool empty() const;
/*! \brief Checks if no filename was given and thus no file uploaded.
* (<b>Deprecated</b>)
*
* Return whether a non-empty filename was given.
*
* \deprecated This method was renamed to empty()
*/
bool emptyFileName() const;
/*! \brief Returns the uploaded files.
*/
const std::vector<Http::UploadedFile>& uploadedFiles() const
{ return uploadedFiles_; }
/*! \brief Returns whether upload() will start a new file upload.
*
* A call to upload() will only start a new file upload if there is
* no JavaScript support. Otherwise, the most recent file will
* already be uploaded.
*
* \if cpp
* \note This method was renamed, and its result inverted, from the
* now deprecated method isUploaded()
* \endif
*/
bool canUpload() const { return fileUploadTarget_ != 0; }
#ifndef WT_DEPRECATED_3_0_0
/*! \brief Returns whether the upload() slot will not start a new
* upload. (<b>Deprecated</b>)
*
* \deprecated use canUpload() instead -- canUpload() == !isUploaded().
* the name was confusing.
*/
bool isUploaded() const { return !canUpload(); }
#endif // WT_DEPRECATED_3_0_0
/*! \brief %Signal emitted when a new file was uploaded.
*
* This signal is emitted when file upload has been completed. It
* is good practice to hide or delete the WFileUpload widget when a
* file has been uploaded succesfully.
*
* \sa upload()
* \sa fileTooLarge()
*/
EventSignal<>& uploaded();
/*! \brief %Signal emitted when the user tried to upload a too large file.
*
* The parameter is the (approximate) size of the file the user
* tried to upload.
*
* The maximum file size is determined by the maximum request size,
* which may be configured in the configuration file (<max-request-size>).
*
* \sa uploaded()
* \sa WApplication::requestTooLarge()
*/
JSignal< ::int64_t >& fileTooLarge() { return fileTooLarge_; }
/*! \brief %Signal emitted when the user selected a new file.
*
* One could react on the user selecting a (new) file, by uploading
* the file immediately.
*
* Caveat: this signal is not emitted with konqueror and possibly
* other browsers. Thus, in the above scenario you should still provide
* an alternative way to call the upload() method.
*/
EventSignal<>& changed();
/*! \brief Starts the file upload.
*
* The uploaded() signal is emitted when a file is uploaded, or the
* fileTooLarge() signal is emitted when the file size exceeded the
* maximum request size.
*
* \sa uploaded()
* \sa canUpload()
*/
void upload();
/*! \brief Sets a progress bar to indicate upload progress.
*
* When the file is being uploaded, upload progress is indicated
* using the provided progress bar. Both the progress bar range and
* values are configured when the upload starts.
*
* If the provided progress bar already has a parent, then the file
* upload itself is hidden as soon as the upload starts. If the
* provided progress bar does not yet have a parent, then the bar
* becomes part of the file upload, and replaces the file prompt
* when the upload is started.
*
* The default progress bar is 0 (no upload progress is indicated).
*
* \if java
* To update the progess bar server push is used, you should only
* use this functionality when using a Servlet 3.0 compatible servlet
* container.
* \endif
*
* \sa dataReceived()
*/
void setProgressBar(WProgressBar *progressBar);
/*! \brief Returns the progress bar.
*
* \sa setProgressBar()
*/
WProgressBar *progressBar() const { return progressBar_; }
/*! \brief %Signal emitted while a file is being uploaded.
*
* When supported by the connector library, you can track the
* progress of the file upload by listening to this signal.
*/
Signal< ::uint64_t, ::uint64_t >& dataReceived() { return dataReceived_; }
virtual void enableAjax();
///
/// \brief Sets input accept attributes
///
/// The accept attribute may be specified to provide user agents with a hint
/// of what file types will be accepted.
/// Use html input accept attributes as input.
///
/// \code
/// WFileUpload *fu = new WFileUpload(root());
/// fu->setFilters("image/*");
/// \endcode
///
void setFilters(const std::string& acceptAttributes);
private:
static const char *CHANGE_SIGNAL;
static const char *UPLOADED_SIGNAL;
static const int BIT_DO_UPLOAD = 0;
static const int BIT_ENABLE_AJAX = 1;
static const int BIT_UPLOADING = 2;
static const int BIT_MULTIPLE = 3;
static const int BIT_ENABLED_CHANGED = 4;
std::bitset<5> flags_;
int textSize_;
std::vector<Http::UploadedFile> uploadedFiles_;
JSignal< ::int64_t > fileTooLarge_;
Signal< ::uint64_t, ::uint64_t > dataReceived_;
WResource *fileUploadTarget_;
WProgressBar *progressBar_;
std::string acceptAttributes_;
void create();
void onData(::uint64_t current, ::uint64_t total);
virtual void setRequestTooLarge(::int64_t size);
protected:
virtual void updateDom(DomElement& element, bool all);
virtual DomElement *createDomElement(WApplication *app);
virtual DomElementType domElementType() const;
virtual void propagateRenderOk(bool deep);
virtual void getDomChanges(std::vector<DomElement *>& result,
WApplication *app);
virtual void propagateSetEnabled(bool enabled);
virtual std::string renderRemoveJs(bool recursive);
private:
void handleFileTooLarge(::int64_t fileSize);
void onUploaded();
virtual void setFormData(const FormData& formData);
void setFiles(const std::vector<Http::UploadedFile>& files);
friend class WFileUploadResource;
};
}
#endif // WFILEUPLOAD_H_
|