void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) { _pack.clear(); if (set.type() == mtpc_messages_stickerSet) { const MTPDmessages_stickerSet &d(set.c_messages_stickerSet()); const QVector<MTPDocument> &v(d.vdocuments.c_vector().v); _pack.reserve(v.size()); for (int32 i = 0, l = v.size(); i < l; ++i) { DocumentData *doc = App::feedDocument(v.at(i)); if (!doc || !doc->sticker()) continue; _pack.push_back(doc); } if (d.vset.type() == mtpc_stickerSet) { const MTPDstickerSet &s(d.vset.c_stickerSet()); _setTitle = qs(s.vtitle); _title = st::boxTitleFont->m.elidedText(_setTitle, Qt::ElideRight, width() - st::btnStickersClose.width - st::boxTitlePos.x()); _setShortName = qs(s.vshort_name); _setId = s.vid.v; _setAccess = s.vaccess_hash.v; _setCount = s.vcount.v; _setHash = s.vhash.v; _setFlags = s.vflags.v; } } if (_pack.isEmpty()) { App::wnd()->showLayer(new ConfirmBox(lang(lng_stickers_not_found), true), true); } else { int32 rows = _pack.size() / StickerPanPerRow + ((_pack.size() % StickerPanPerRow) ? 1 : 0); resize(st::stickersPadding + StickerPanPerRow * st::stickersSize.width(), rows * st::stickersSize.height() + st::stickersAddOrShare); } _loaded = true; emit updateButtons(); }
/** This method starts by pushing a DocumentData object created from the index document to the _documentStack. Then the iteration loop is started which ends when all DocumentData objects are popped from the _documentStack. Each DocumentData object contains a well-formed XML representaion of the underlying input document. Additionally it provides a pointer to the node of the application's internal tree structure to which the document will be added to. This XML representation is passed to a QDomDocument object which validates it and retrieves the root element. Then the _readElement() method processes the document with the given root element. @author Bjoern */ Node* DocumentReader::read(QString indexfilepath, DocumentData::FileType filetype) { if (_translationMapper == 0) { if (Settings::DEBUG) std::cerr << tr("DocumentReader.read() : _translationMapper is 0").toStdString() << std::endl; return 0; } Settings settings; _includeSubDocuments = (bool)settings.getValue("includesubdocuments").toInt(); _fileType = filetype; _indexFileInfo = QFileInfo(indexfilepath); // start reading the whole document tree Node* root = new Node(0, "html", 0); // add the index document to the stack of documents _documentStack.push(new DocumentData(_indexFileInfo, root, _fileType)); // begin processing the documents stored on the document stack while(!_documentStack.isEmpty()) { DocumentData* documentdata = _documentStack.pop(); QDomDocument doc; QString errorStr = ""; int errorLine = -1; int errorColumn = -1; if (doc.setContent(documentdata->text().toLatin1(), false, &errorStr, &errorLine, &errorColumn)) { if (doc.documentElement().tagName().toLower() == "html") _readElement(doc.documentElement(), documentdata->node()); else { std::cerr << tr("Error in DocumentReader::read()").toStdString() << std::endl << tr("\tat \"if (doc.setContent())\" returned false;").toStdString() << std::endl << tr("\tFile name: ").toStdString() << documentdata->fileInfo().filePath().toStdString() << std::endl << tr("\tError message: <html>-tag not found").toStdString() << std::endl; } } else { std::cerr << "Error in CDocumentReader::read()" << std::endl << "\tat doc.setContent() returned false;" << std::endl << "\tFile name: " << documentdata->fileInfo().filePath().toStdString() << std::endl << "\tError message: " << std::endl << errorStr.toStdString() << " line=" << std::endl << QString::number(errorLine).toStdString() << std::endl << "\tColumn=" << QString::number(errorColumn).toStdString() << std::endl; } delete documentdata; } return root; };
void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) { QMap<mtpRequestId, int32>::iterator j = docRequestsSent.end(); QMap<mtpRequestId, QByteArray>::iterator i = requestsSent.find(requestId); if (i == requestsSent.cend()) { j = docRequestsSent.find(requestId); } if (i != requestsSent.cend() || j != docRequestsSent.cend()) { if (mtpIsFalse(result)) { // failed to upload current file currentFailed(); return; } else { QMap<mtpRequestId, int32>::iterator dcIt = dcMap.find(requestId); if (dcIt == dcMap.cend()) { // must not happen currentFailed(); return; } int32 dc = dcIt.value(); dcMap.erase(dcIt); int32 sentPartSize = 0; Queue::const_iterator k = queue.constFind(uploading); if (i != requestsSent.cend()) { sentPartSize = i.value().size(); requestsSent.erase(i); } else { sentPartSize = k->docPartSize; docRequestsSent.erase(j); } sentSize -= sentPartSize; sentSizes[dc] -= sentPartSize; if (k->type() == PreparePhoto) { k->fileSentSize += sentPartSize; PhotoData *photo = App::photo(k->id()); if (photo->uploading() && k->file) { photo->uploadingData->size = k->file->partssize; photo->uploadingData->offset = k->fileSentSize; } emit photoProgress(k.key()); } else if (k->type() == PrepareDocument || k->type() == PrepareAudio) { DocumentData *doc = App::document(k->id()); if (doc->uploading()) { doc->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize; if (doc->uploadOffset > doc->size) { doc->uploadOffset = doc->size; } } emit documentProgress(k.key()); } } } sendNext(); }
void StickerSetInner::paintEvent(QPaintEvent *e) { QRect r(e->rect()); Painter p(this); if (_pack.isEmpty()) return; int32 rows = _pack.size() / StickerPanPerRow + ((_pack.size() % StickerPanPerRow) ? 1 : 0); int32 from = qFloor(e->rect().top() / st::stickersSize.height()), to = qFloor(e->rect().bottom() / st::stickersSize.height()) + 1; for (int32 i = from; i < to; ++i) { for (int32 j = 0; j < StickerPanPerRow; ++j) { int32 index = i * StickerPanPerRow + j; if (index >= _pack.size()) break; DocumentData *doc = _pack.at(index); QPoint pos(st::stickerPanPadding + j * st::stickersSize.width(), i * st::stickersSize.height()); bool goodThumb = !doc->thumb->isNull() && ((doc->thumb->width() >= 128) || (doc->thumb->height() >= 128)); if (goodThumb) { doc->thumb->load(); } else { bool already = !doc->already().isEmpty(), hasdata = !doc->data.isEmpty(); if (!doc->loader && doc->status != FileFailed && !already && !hasdata) { doc->save(QString()); } if (doc->sticker->img->isNull() && (already || hasdata)) { if (already) { doc->sticker->img = ImagePtr(doc->already()); } else { doc->sticker->img = ImagePtr(doc->data); } } } float64 coef = qMin((st::stickersSize.width() - st::msgRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::msgRadius * 2) / float64(doc->dimensions.height())); if (coef > 1) coef = 1; int32 w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height()); if (w < 1) w = 1; if (h < 1) h = 1; QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2); if (goodThumb) { p.drawPixmapLeft(ppos, width(), doc->thumb->pix(w, h)); } else if (!doc->sticker->img->isNull()) { p.drawPixmapLeft(ppos, width(), doc->sticker->img->pix(w, h)); } } } p.fillRect(0, _bottom - st::stickersAddOrShare, width(), st::stickersAddOrShare, st::emojiPanHeaderBg->b); }
// Adds all the documents in the list of filenames, couting memory. // The reader is used to read the files. bool DocumentCache::LoadDocuments(const GenericVector<STRING>& filenames, const char* lang, FileReader reader) { for (int arg = 0; arg < filenames.size(); ++arg) { STRING filename = filenames[arg] + ".lstmf"; DocumentData* document = new DocumentData(filename); if (document->LoadDocument(filename.string(), lang, reader)) { AddToCache(document); tprintf("File %d, count=%d\n", arg, document->pages().size()); } else { tprintf("Failed to load image %s!\n", filename.string()); delete document; } } tprintf("Loaded %d pages, total %gMB\n", total_pages_, memory_used_ / 1048576.0); return total_pages_ > 0; }
void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &media) { if (media.type == PreparePhoto) { App::feedPhoto(media.photo, media.photoThumbs); } else if (media.type == PrepareDocument || media.type == PrepareAudio) { DocumentData *document; if (media.photoThumbs.isEmpty()) { document = App::feedDocument(media.document); } else { document = App::feedDocument(media.document, media.photoThumbs.begin().value()); } document->status = FileUploading; if (!media.data.isEmpty()) { document->setData(media.data); } if (!media.file.isEmpty()) { document->setLocation(FileLocation(StorageFilePartial, media.file)); } } queue.insert(msgId, File(media)); sendNext(); }
void PlayerWidget::preloadNext() { if (_index < 0) return; History *history = _msgmigrated ? _migrated : _history; const History::MediaOverview *o = &history->overview[OverviewAudioDocuments]; HistoryItem *next = 0; if (_index < o->size() - 1) { next = App::histItemById(history->channelId(), o->at(_index + 1)); } else if (_msgmigrated && _index == o->size() - 1 && _history->overviewLoaded(OverviewAudioDocuments) && _history->overviewCount(OverviewAudioDocuments) > 0) { next = App::histItemById(_history->channelId(), _history->overview[OverviewAudioDocuments].at(0)); } else if (_msgmigrated && _index == o->size() - 1 && !_history->overviewCountLoaded(OverviewAudioDocuments)) { if (App::main()) App::main()->preloadOverview(_history->peer, OverviewAudioDocuments); } if (next) { if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) { DocumentData *d = document->getDocument(); if (!d->loaded(true)) { DocumentOpenLink::doOpen(d, ActionOnLoadNone); } } } }
void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file) { if (file->type == PreparePhoto) { PhotoData *photo = App::feedPhoto(file->photo, file->photoThumbs); photo->uploadingData = new PhotoData::UploadingData(file->partssize); } else if (file->type == PrepareDocument || file->type == PrepareAudio) { DocumentData *document; if (file->thumb.isNull()) { document = App::feedDocument(file->document); } else { document = App::feedDocument(file->document, file->thumb); } document->status = FileUploading; if (!file->content.isEmpty()) { document->setData(file->content); } if (!file->filepath.isEmpty()) { document->setLocation(FileLocation(StorageFilePartial, file->filepath)); } } queue.insert(msgId, File(file)); sendNext(); }
void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result) { _stickerSetRequests.remove(setId); if (result.type() != mtpc_messages_stickerSet) return; const MTPDmessages_stickerSet &d(result.c_messages_stickerSet()); if (d.vset.type() != mtpc_stickerSet) return; const MTPDstickerSet &s(d.vset.c_stickerSet()); StickerSets &sets(cRefStickerSets()); StickerSets::iterator it = sets.find(setId); if (it == sets.cend()) return; it->access = s.vaccess_hash.v; it->hash = s.vhash.v; it->shortName = qs(s.vshort_name); it->title = stickerSetTitle(s); it->flags = s.vflags.v; const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v); StickerSets::iterator custom = sets.find(CustomStickerSetId); StickerPack pack; pack.reserve(d_docs.size()); for (int32 i = 0, l = d_docs.size(); i != l; ++i) { DocumentData *doc = App::feedDocument(d_docs.at(i)); if (!doc || !doc->sticker()) continue; pack.push_back(doc); if (custom != sets.cend()) { int32 index = custom->stickers.indexOf(doc); if (index >= 0) { custom->stickers.removeAt(index); } } } if (custom != sets.cend() && custom->stickers.isEmpty()) { sets.erase(custom); custom = sets.end(); } bool writeRecent = false; RecentStickerPack &recent(cGetRecentStickers()); for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) { if (it->stickers.indexOf(i->first) >= 0 && pack.indexOf(i->first) < 0) { i = recent.erase(i); writeRecent = true; } else { ++i; } } if (pack.isEmpty()) { int32 removeIndex = cStickerSetsOrder().indexOf(setId); if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex); sets.erase(it); } else { it->stickers = pack; } if (writeRecent) { Local::writeUserSettings(); } Local::writeStickers(); if (App::main()) emit App::main()->stickersUpdated(); }
void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result) { _stickerSetRequests.remove(setId); if (result.type() != mtpc_messages_stickerSet) return; const MTPDmessages_stickerSet &d(result.c_messages_stickerSet()); if (d.vset.type() != mtpc_stickerSet) return; const MTPDstickerSet &s(d.vset.c_stickerSet()); StickerSets &sets(cRefStickerSets()); StickerSets::iterator it = sets.find(setId); if (it == sets.cend()) return; it->access = s.vaccess_hash.v; it->hash = s.vhash.v; it->shortName = qs(s.vshort_name); QString title = qs(s.vtitle); if ((it->flags & MTPDstickerSet_flag_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) { title = lang(lng_stickers_default_set); } it->title = title; it->flags = s.vflags.v; const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v); StickerSets::iterator custom = sets.find(CustomStickerSetId); QSet<DocumentData*> found; int32 wasCount = -1; for (int32 i = 0, l = d_docs.size(); i != l; ++i) { DocumentData *doc = App::feedDocument(d_docs.at(i)); if (!doc || !doc->sticker()) continue; if (wasCount < 0) wasCount = it->stickers.size(); if (it->stickers.indexOf(doc) < 0) { it->stickers.push_back(doc); } else { found.insert(doc); } if (custom != sets.cend()) { int32 index = custom->stickers.indexOf(doc); if (index >= 0) { custom->stickers.removeAt(index); } } } if (custom != sets.cend() && custom->stickers.isEmpty()) { sets.erase(custom); custom = sets.end(); } bool writeRecent = false; RecentStickerPack &recent(cGetRecentStickers()); if (wasCount < 0) { // no stickers received for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) { if (it->stickers.indexOf(i->first) >= 0) { i = recent.erase(i); writeRecent = true; } else { ++i; } } cRefStickerSetsOrder().removeOne(setId); sets.erase(it); } else { for (int32 j = 0, l = wasCount; j < l;) { if (found.contains(it->stickers.at(j))) { ++j; } else { for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) { if (it->stickers.at(j) == i->first) { i = recent.erase(i); writeRecent = true; } else { ++i; } } it->stickers.removeAt(j); --l; } } if (it->stickers.isEmpty()) { cRefStickerSetsOrder().removeOne(setId); sets.erase(it); } } if (writeRecent) { Local::writeUserSettings(); } Local::writeStickers(); if (App::main()) emit App::main()->stickersUpdated(); }
EditCaptionBox::EditCaptionBox( QWidget*, not_null<HistoryItem*> item) : _msgId(item->fullId()) { Expects(item->media() != nullptr); Expects(item->media()->allowsEditCaption()); QSize dimensions; ImagePtr image; DocumentData *doc = nullptr; const auto media = item->media(); if (const auto photo = media->photo()) { _photo = true; dimensions = QSize(photo->full->width(), photo->full->height()); image = photo->full; } else if (const auto document = media->document()) { dimensions = document->dimensions; image = document->thumb; if (document->isAnimation()) { _animated = true; } else if (document->isVideoFile()) { _animated = true; } else { _doc = true; } doc = document; } auto caption = item->originalText().text; if (!_animated && (dimensions.isEmpty() || doc || image->isNull())) { if (image->isNull()) { _thumbw = 0; } else { int32 tw = image->width(), th = image->height(); if (tw > th) { _thumbw = (tw * st::msgFileThumbSize) / th; } else { _thumbw = st::msgFileThumbSize; } auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomRight; _thumb = Images::pixmap(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, options, st::msgFileThumbSize, st::msgFileThumbSize); } if (doc) { auto nameString = doc->isVoiceMessage() ? lang(lng_media_audio) : doc->composeNameString(); _name.setText( st::semiboldTextStyle, nameString, Ui::NameTextOptions()); _status = formatSizeText(doc->size); _statusw = qMax( _name.maxWidth(), st::normalFont->width(_status)); _isImage = doc->isImage(); _isAudio = (doc->isVoiceMessage() || doc->isAudioFile()); } } else { int32 maxW = 0, maxH = 0; if (_animated) { int32 limitW = st::sendMediaPreviewSize; int32 limitH = st::confirmMaxHeight; maxW = qMax(dimensions.width(), 1); maxH = qMax(dimensions.height(), 1); if (maxW * limitH > maxH * limitW) { if (maxW < limitW) { maxH = maxH * limitW / maxW; maxW = limitW; } } else { if (maxH < limitH) { maxW = maxW * limitH / maxH; maxH = limitH; } } _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth | Images::Option::Blurred, maxW, maxH); prepareGifPreview(doc); } else { maxW = dimensions.width(); maxH = dimensions.height(); _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth, maxW, maxH); } int32 tw = _thumb.width(), th = _thumb.height(); if (!tw || !th) { tw = th = 1; } _thumbw = st::sendMediaPreviewSize; if (_thumb.width() < _thumbw) { _thumbw = (_thumb.width() > 20) ? _thumb.width() : 20; } int32 maxthumbh = qMin(qRound(1.5 * _thumbw), int(st::confirmMaxHeight)); _thumbh = qRound(th * float64(_thumbw) / tw); if (_thumbh > maxthumbh) { _thumbw = qRound(_thumbw * float64(maxthumbh) / _thumbh); _thumbh = maxthumbh; if (_thumbw < 10) { _thumbw = 10; } } _thumbx = (st::boxWideWidth - _thumbw) / 2; _thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _thumb.setDevicePixelRatio(cRetinaFactor()); } Assert(_animated || _photo || _doc); _field.create(this, st::confirmCaptionArea, langFactory(lng_photo_caption), caption); _field->setMaxLength(MaxPhotoCaption); _field->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); }