Пример #1
0
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();
}
Пример #2
0
/** 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;
};
Пример #3
0
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();
}
Пример #4
0
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);
}
Пример #5
0
// 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;
}
Пример #6
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();
}
Пример #7
0
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);
			}
		}
	}
}
Пример #8
0
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();
}
Пример #9
0
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();
}
Пример #10
0
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();
}
Пример #11
0
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);
}