mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add test_text test app.
This commit is contained in:
parent
ffd54c452c
commit
a98f559066
6 changed files with 491 additions and 1 deletions
|
@ -37,6 +37,10 @@ include(cmake/td_scheme.cmake)
|
||||||
include(cmake/td_ui.cmake)
|
include(cmake/td_ui.cmake)
|
||||||
include(cmake/generate_appdata_changelog.cmake)
|
include(cmake/generate_appdata_changelog.cmake)
|
||||||
|
|
||||||
|
if (DESKTOP_APP_TEST_APPS)
|
||||||
|
include(cmake/tests.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
include(cmake/generate_midl.cmake)
|
include(cmake/generate_midl.cmake)
|
||||||
generate_midl(Telegram ${src_loc}
|
generate_midl(Telegram ${src_loc}
|
||||||
|
|
219
Telegram/SourceFiles/tests/test_main.cpp
Normal file
219
Telegram/SourceFiles/tests/test_main.cpp
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "tests/test_main.h"
|
||||||
|
|
||||||
|
#include "base/invoke_queued.h"
|
||||||
|
#include "base/integration.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
#include "ui/widgets/rp_window.h"
|
||||||
|
#include "ui/emoji_config.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include <qpa/qplatformscreen.h>
|
||||||
|
|
||||||
|
namespace Test {
|
||||||
|
|
||||||
|
bool App::notifyOrInvoke(QObject *receiver, QEvent *e) {
|
||||||
|
if (e->type() == base::InvokeQueuedEvent::Type()) {
|
||||||
|
static_cast<base::InvokeQueuedEvent*>(e)->invoke();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return QApplication::notify(receiver, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool App::nativeEventFilter(
|
||||||
|
const QByteArray &eventType,
|
||||||
|
void *message,
|
||||||
|
native_event_filter_result *result) {
|
||||||
|
registerEnterFromEventLoop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::checkForEmptyLoopNestingLevel() {
|
||||||
|
// _loopNestingLevel == _eventNestingLevel means that we had a
|
||||||
|
// native event in a nesting loop that didn't get a notify() call
|
||||||
|
// after. That means we already have exited the nesting loop and
|
||||||
|
// there must not be any postponed calls with that nesting level.
|
||||||
|
if (_loopNestingLevel == _eventNestingLevel) {
|
||||||
|
Assert(_postponedCalls.empty()
|
||||||
|
|| _postponedCalls.back().loopNestingLevel < _loopNestingLevel);
|
||||||
|
Assert(!_previousLoopNestingLevels.empty());
|
||||||
|
|
||||||
|
_loopNestingLevel = _previousLoopNestingLevels.back();
|
||||||
|
_previousLoopNestingLevels.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::postponeCall(FnMut<void()> &&callable) {
|
||||||
|
Expects(callable != nullptr);
|
||||||
|
Expects(_eventNestingLevel >= _loopNestingLevel);
|
||||||
|
|
||||||
|
checkForEmptyLoopNestingLevel();
|
||||||
|
_postponedCalls.push_back({
|
||||||
|
_loopNestingLevel,
|
||||||
|
std::move(callable)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::processPostponedCalls(int level) {
|
||||||
|
while (!_postponedCalls.empty()) {
|
||||||
|
auto &last = _postponedCalls.back();
|
||||||
|
if (last.loopNestingLevel != level) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto taken = std::move(last);
|
||||||
|
_postponedCalls.pop_back();
|
||||||
|
taken.callable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::incrementEventNestingLevel() {
|
||||||
|
++_eventNestingLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::decrementEventNestingLevel() {
|
||||||
|
Expects(_eventNestingLevel >= _loopNestingLevel);
|
||||||
|
|
||||||
|
if (_eventNestingLevel == _loopNestingLevel) {
|
||||||
|
_loopNestingLevel = _previousLoopNestingLevels.back();
|
||||||
|
_previousLoopNestingLevels.pop_back();
|
||||||
|
}
|
||||||
|
const auto processTillLevel = _eventNestingLevel - 1;
|
||||||
|
processPostponedCalls(processTillLevel);
|
||||||
|
checkForEmptyLoopNestingLevel();
|
||||||
|
_eventNestingLevel = processTillLevel;
|
||||||
|
|
||||||
|
Ensures(_eventNestingLevel >= _loopNestingLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::registerEnterFromEventLoop() {
|
||||||
|
Expects(_eventNestingLevel >= _loopNestingLevel);
|
||||||
|
|
||||||
|
if (_eventNestingLevel > _loopNestingLevel) {
|
||||||
|
_previousLoopNestingLevels.push_back(_loopNestingLevel);
|
||||||
|
_loopNestingLevel = _eventNestingLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool App::notify(QObject *receiver, QEvent *e) {
|
||||||
|
if (QThread::currentThreadId() != _mainThreadId) {
|
||||||
|
return notifyOrInvoke(receiver, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto wrap = createEventNestingLevel();
|
||||||
|
if (e->type() == QEvent::UpdateRequest) {
|
||||||
|
const auto weak = QPointer<QObject>(receiver);
|
||||||
|
_widgetUpdateRequests.fire({});
|
||||||
|
if (!weak) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notifyOrInvoke(receiver, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> App::widgetUpdateRequests() const {
|
||||||
|
return _widgetUpdateRequests.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIntegration::enterFromEventLoop(FnMut<void()> &&method) {
|
||||||
|
app().customEnterFromEventLoop(std::move(method));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIntegration::logSkipDebug() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIntegration::logMessageDebug(const QString &message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIntegration::logMessage(const QString &message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::postponeCall(FnMut<void()> &&callable) {
|
||||||
|
app().postponeCall(std::move(callable));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::registerLeaveSubscription(not_null<QWidget*> widget) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::unregisterLeaveSubscription(not_null<QWidget*> widget) {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::emojiCacheFolder() {
|
||||||
|
return QDir().currentPath() + "/tests/" + name() + "/emoji";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::openglCheckFilePath() {
|
||||||
|
return QDir().currentPath() + "/tests/" + name() + "/opengl";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::angleBackendFilePath() {
|
||||||
|
return QDir().currentPath() + "/test/" + name() + "/angle";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Test
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
using namespace Test;
|
||||||
|
|
||||||
|
auto app = App(argc, argv);
|
||||||
|
app.installNativeEventFilter(&app);
|
||||||
|
|
||||||
|
const auto ratio = app.devicePixelRatio();
|
||||||
|
const auto useRatio = std::clamp(qCeil(ratio), 1, 3);
|
||||||
|
style::SetDevicePixelRatio(useRatio);
|
||||||
|
|
||||||
|
const auto screen = App::primaryScreen();
|
||||||
|
const auto dpi = screen->logicalDotsPerInch();
|
||||||
|
const auto basePair = screen->handle()->logicalBaseDpi();
|
||||||
|
const auto baseMiddle = (basePair.first + basePair.second) * 0.5;
|
||||||
|
const auto screenExact = dpi / baseMiddle;
|
||||||
|
const auto screenScale = int(base::SafeRound(screenExact * 20)) * 5;
|
||||||
|
const auto chosen = std::clamp(
|
||||||
|
screenScale,
|
||||||
|
style::kScaleMin,
|
||||||
|
style::MaxScaleForRatio(useRatio));
|
||||||
|
|
||||||
|
BaseIntegration base(argc, argv);
|
||||||
|
base::Integration::Set(&base);
|
||||||
|
|
||||||
|
UiIntegration ui;
|
||||||
|
Ui::Integration::Set(&ui);
|
||||||
|
|
||||||
|
InvokeQueued(&app, [=] {
|
||||||
|
new Ui::Animations::Manager();
|
||||||
|
style::StartManager(chosen);
|
||||||
|
|
||||||
|
Ui::Emoji::Init();
|
||||||
|
|
||||||
|
const auto window = new Ui::RpWindow();
|
||||||
|
window->setGeometry(
|
||||||
|
{ scale(100), scale(100), scale(800), scale(600) });
|
||||||
|
window->show();
|
||||||
|
|
||||||
|
window->setMinimumSize({ scale(240), scale(320) });
|
||||||
|
|
||||||
|
test(window, window->body());
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace crl {
|
||||||
|
|
||||||
|
rpl::producer<> on_main_update_requests() {
|
||||||
|
return Test::app().widgetUpdateRequests();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crl
|
110
Telegram/SourceFiles/tests/test_main.h
Normal file
110
Telegram/SourceFiles/tests/test_main.h
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/basic_types.h"
|
||||||
|
#include "base/integration.h"
|
||||||
|
#include "ui/style/style_core_scale.h"
|
||||||
|
#include "ui/integration.h"
|
||||||
|
|
||||||
|
#include <crl/crl.h>
|
||||||
|
#include <rpl/rpl.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RpWidget;
|
||||||
|
class RpWindow;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Test {
|
||||||
|
|
||||||
|
[[nodiscard]] QString name();
|
||||||
|
|
||||||
|
void test(not_null<Ui::RpWindow*> window, not_null<Ui::RpWidget*> widget);
|
||||||
|
|
||||||
|
[[nodiscard]] inline int scale(int value) {
|
||||||
|
return style::ConvertScale(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
class App final : public QApplication, public QAbstractNativeEventFilter {
|
||||||
|
public:
|
||||||
|
using QApplication::QApplication;
|
||||||
|
|
||||||
|
template <typename Callable>
|
||||||
|
auto customEnterFromEventLoop(Callable &&callable) {
|
||||||
|
registerEnterFromEventLoop();
|
||||||
|
const auto wrap = createEventNestingLevel();
|
||||||
|
return callable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void postponeCall(FnMut<void()> &&callable);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<> widgetUpdateRequests() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct PostponedCall {
|
||||||
|
int loopNestingLevel = 0;
|
||||||
|
FnMut<void()> callable;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto createEventNestingLevel() {
|
||||||
|
incrementEventNestingLevel();
|
||||||
|
return gsl::finally([=] { decrementEventNestingLevel(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkForEmptyLoopNestingLevel();
|
||||||
|
void processPostponedCalls(int level);
|
||||||
|
void incrementEventNestingLevel();
|
||||||
|
void decrementEventNestingLevel();
|
||||||
|
void registerEnterFromEventLoop();
|
||||||
|
|
||||||
|
bool notifyOrInvoke(QObject *receiver, QEvent *e);
|
||||||
|
bool notify(QObject *receiver, QEvent *e) override;
|
||||||
|
bool nativeEventFilter(
|
||||||
|
const QByteArray &eventType,
|
||||||
|
void *message,
|
||||||
|
native_event_filter_result *result) override;
|
||||||
|
|
||||||
|
rpl::event_stream<> _widgetUpdateRequests;
|
||||||
|
Qt::HANDLE _mainThreadId = QThread::currentThreadId();
|
||||||
|
int _eventNestingLevel = 0;
|
||||||
|
int _loopNestingLevel = 0;
|
||||||
|
std::vector<int> _previousLoopNestingLevels;
|
||||||
|
std::vector<PostponedCall> _postponedCalls;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline App &app() {
|
||||||
|
return *static_cast<App*>(QCoreApplication::instance());
|
||||||
|
}
|
||||||
|
|
||||||
|
class BaseIntegration final : public base::Integration {
|
||||||
|
public:
|
||||||
|
using Integration::Integration;
|
||||||
|
|
||||||
|
void enterFromEventLoop(FnMut<void()> &&method);
|
||||||
|
bool logSkipDebug();
|
||||||
|
void logMessageDebug(const QString &message);
|
||||||
|
void logMessage(const QString &message);
|
||||||
|
};
|
||||||
|
|
||||||
|
class UiIntegration final : public Ui::Integration {
|
||||||
|
public:
|
||||||
|
void postponeCall(FnMut<void()> &&callable);
|
||||||
|
void registerLeaveSubscription(not_null<QWidget*> widget);
|
||||||
|
void unregisterLeaveSubscription(not_null<QWidget*> widget);
|
||||||
|
QString emojiCacheFolder();
|
||||||
|
QString openglCheckFilePath();
|
||||||
|
QString angleBackendFilePath();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Test
|
113
Telegram/SourceFiles/tests/test_text.cpp
Normal file
113
Telegram/SourceFiles/tests/test_text.cpp
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "tests/test_main.h"
|
||||||
|
|
||||||
|
#include "base/invoke_queued.h"
|
||||||
|
#include "base/integration.h"
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
#include "ui/text/text.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/widgets/rp_window.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
namespace Test {
|
||||||
|
|
||||||
|
QString name() {
|
||||||
|
return u"text"_q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(not_null<Ui::RpWindow*> window, not_null<Ui::RpWidget*> body) {
|
||||||
|
auto text = new Ui::Text::String(scale(64));
|
||||||
|
|
||||||
|
const auto like = QString::fromUtf8("\xf0\x9f\x91\x8d");
|
||||||
|
const auto dislike = QString::fromUtf8("\xf0\x9f\x91\x8e");
|
||||||
|
const auto hebrew = QString() + QChar(1506) + QChar(1460) + QChar(1489);
|
||||||
|
|
||||||
|
auto data = TextWithEntities();
|
||||||
|
data.append(
|
||||||
|
u"Lorem ipsu7m dolor sit amet, "_q
|
||||||
|
).append(Ui::Text::Bold(
|
||||||
|
u"consectetur adipiscing: "_q
|
||||||
|
+ hebrew
|
||||||
|
+ u" elit, sed do eiusmod tempor incididunt test"_q
|
||||||
|
)).append(Ui::Text::Wrapped(Ui::Text::Bold(
|
||||||
|
u". ut labore et dolore magna aliqua."_q
|
||||||
|
+ like
|
||||||
|
+ dislike
|
||||||
|
+ u"Ut enim ad minim veniam"_q
|
||||||
|
), EntityType::Italic)).append(
|
||||||
|
u", quis nostrud exercitation ullamco laboris nisi ut aliquip ex \
|
||||||
|
ea commodo consequat. Duis aute irure dolor in reprehenderit in \
|
||||||
|
voluptate velit esse cillum dolore eu fugiat nulla pariatur. \
|
||||||
|
Excepteur sint occaecat cupidatat non proident, sunt in culpa \
|
||||||
|
qui officia deserunt mollit anim id est laborum."_q
|
||||||
|
).append(u"\n\n"_q).append(hebrew).append("\n\n").append(
|
||||||
|
"Duisauteiruredolorinreprehenderitinvoluptatevelitessecillumdoloreeu\
|
||||||
|
fugiatnullapariaturExcepteursintoccaecatcupidatatnonproident, sunt in culpa \
|
||||||
|
qui officia deserunt mollit anim id est laborum. \
|
||||||
|
Duisauteiruredolorinreprehenderitinvoluptate.");
|
||||||
|
data.append(data);
|
||||||
|
//data.append("hi\n\nguys");
|
||||||
|
text->setMarkedText(st::defaultTextStyle, data);
|
||||||
|
|
||||||
|
body->paintRequest() | rpl::start_with_next([=](QRect clip) {
|
||||||
|
auto p = QPainter(body);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
|
||||||
|
const auto width = body->width();
|
||||||
|
const auto height = body->height();
|
||||||
|
|
||||||
|
p.fillRect(clip, QColor(255, 255, 255));
|
||||||
|
|
||||||
|
const auto border = QColor(0, 128, 0, 16);
|
||||||
|
auto skip = scale(20);
|
||||||
|
p.fillRect(0, 0, skip, height, border);
|
||||||
|
p.fillRect(skip, 0, width - skip, skip, border);
|
||||||
|
p.fillRect(skip, height - skip, width - skip, skip, border);
|
||||||
|
p.fillRect(width - skip, skip, skip, height - skip * 2, border);
|
||||||
|
|
||||||
|
const auto inner = body->rect().marginsRemoved(
|
||||||
|
{ skip, skip, skip, skip });
|
||||||
|
|
||||||
|
p.fillRect(QRect{
|
||||||
|
inner.x(),
|
||||||
|
inner.y(),
|
||||||
|
inner.width(),
|
||||||
|
text->countHeight(inner.width())
|
||||||
|
}, QColor(128, 0, 0, 16));
|
||||||
|
|
||||||
|
auto widths = text->countLineWidths(inner.width());
|
||||||
|
auto top = 0;
|
||||||
|
for (const auto width : widths) {
|
||||||
|
p.fillRect(QRect{
|
||||||
|
inner.x(),
|
||||||
|
inner.y() + top,
|
||||||
|
width,
|
||||||
|
st::defaultTextStyle.font->height
|
||||||
|
}, QColor(0, 0, 128, 16));
|
||||||
|
top += st::defaultTextStyle.font->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
text->draw(p, {
|
||||||
|
.position = inner.topLeft(),
|
||||||
|
.availableWidth = inner.width(),
|
||||||
|
});
|
||||||
|
|
||||||
|
//const auto to = QRectF(
|
||||||
|
// inner.marginsRemoved({ 0, inner.height() / 2, 0, 0 }));
|
||||||
|
//const auto t = u"hi\n\nguys"_q;
|
||||||
|
//p.drawText(to, t);
|
||||||
|
}, body->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Test
|
44
Telegram/cmake/tests.cmake
Normal file
44
Telegram/cmake/tests.cmake
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# This file is part of Telegram Desktop,
|
||||||
|
# the official desktop application for the Telegram messaging service.
|
||||||
|
#
|
||||||
|
# For license and copyright information please follow this link:
|
||||||
|
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
|
add_executable(test_text WIN32)
|
||||||
|
init_target(test_text "(tests)")
|
||||||
|
|
||||||
|
target_include_directories(test_text PRIVATE ${src_loc})
|
||||||
|
|
||||||
|
nice_target_sources(test_text ${src_loc}
|
||||||
|
PRIVATE
|
||||||
|
tests/test_main.cpp
|
||||||
|
tests/test_main.h
|
||||||
|
tests/test_text.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
nice_target_sources(test_text ${res_loc}
|
||||||
|
PRIVATE
|
||||||
|
qrc/emoji_1.qrc
|
||||||
|
qrc/emoji_2.qrc
|
||||||
|
qrc/emoji_3.qrc
|
||||||
|
qrc/emoji_4.qrc
|
||||||
|
qrc/emoji_5.qrc
|
||||||
|
qrc/emoji_6.qrc
|
||||||
|
qrc/emoji_7.qrc
|
||||||
|
qrc/emoji_8.qrc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(test_text
|
||||||
|
PRIVATE
|
||||||
|
desktop-app::lib_base
|
||||||
|
desktop-app::lib_crl
|
||||||
|
desktop-app::lib_ui
|
||||||
|
desktop-app::external_qt
|
||||||
|
desktop-app::external_qt_static_plugins
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(test_text PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
add_dependencies(Telegram test_text)
|
||||||
|
|
||||||
|
target_prepare_qrc(test_text)
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
||||||
Subproject commit 7b11e62e2a40a3dab7f039d4953f1514c73cb6d5
|
Subproject commit af43537447ebdc2a241c0cdad615e794a840665a
|
Loading…
Add table
Reference in a new issue