mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 04:53:36 +00:00
[ios] Format all Obj C code via clang-format
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
@@ -7,19 +7,19 @@
|
||||
|
||||
@implementation MWMBookmark (Core)
|
||||
|
||||
- (instancetype)initWithMarkId:(MWMMarkID)markId bookmarkData:(Bookmark const *)bookmark {
|
||||
- (instancetype)initWithMarkId:(MWMMarkID)markId bookmarkData:(Bookmark const *)bookmark
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_bookmarkId = markId;
|
||||
_bookmarkName = @(bookmark->GetPreferredName().c_str());
|
||||
_bookmarkColor = convertKmlColor(bookmark->GetColor());
|
||||
_bookmarkIconName = [NSString stringWithFormat:@"%@%@",
|
||||
@"ic_bm_",
|
||||
[@(kml::ToString(bookmark->GetData().m_icon).c_str()) lowercaseString]];
|
||||
_bookmarkIconName = [NSString
|
||||
stringWithFormat:@"%@%@", @"ic_bm_", [@(kml::ToString(bookmark->GetData().m_icon).c_str()) lowercaseString]];
|
||||
auto const & types = bookmark->GetData().m_featureTypes;
|
||||
if (!types.empty()) {
|
||||
if (!types.empty())
|
||||
_bookmarkType = @(kml::GetLocalizedFeatureType(types).c_str());
|
||||
}
|
||||
auto latlon = bookmark->GetLatLon();
|
||||
_locationCoordinate = CLLocationCoordinate2DMake(latlon.m_lat, latlon.m_lon);
|
||||
}
|
||||
|
||||
@@ -1,42 +1,26 @@
|
||||
#import "MWMBookmarkColor+Core.h"
|
||||
|
||||
MWMBookmarkColor convertKmlColor(kml::PredefinedColor kmlColor) {
|
||||
switch (kmlColor) {
|
||||
case kml::PredefinedColor::None:
|
||||
return MWMBookmarkColorNone;
|
||||
case kml::PredefinedColor::Red:
|
||||
return MWMBookmarkColorRed;
|
||||
case kml::PredefinedColor::Blue:
|
||||
return MWMBookmarkColorBlue;
|
||||
case kml::PredefinedColor::Purple:
|
||||
return MWMBookmarkColorPurple;
|
||||
case kml::PredefinedColor::Yellow:
|
||||
return MWMBookmarkColorYellow;
|
||||
case kml::PredefinedColor::Pink:
|
||||
return MWMBookmarkColorPink;
|
||||
case kml::PredefinedColor::Brown:
|
||||
return MWMBookmarkColorBrown;
|
||||
case kml::PredefinedColor::Green:
|
||||
return MWMBookmarkColorGreen;
|
||||
case kml::PredefinedColor::Orange:
|
||||
return MWMBookmarkColorOrange;
|
||||
case kml::PredefinedColor::DeepPurple:
|
||||
return MWMBookmarkColorDeepPurple;
|
||||
case kml::PredefinedColor::LightBlue:
|
||||
return MWMBookmarkColorLightBlue;
|
||||
case kml::PredefinedColor::Cyan:
|
||||
return MWMBookmarkColorCyan;
|
||||
case kml::PredefinedColor::Teal:
|
||||
return MWMBookmarkColorTeal;
|
||||
case kml::PredefinedColor::Lime:
|
||||
return MWMBookmarkColorLime;
|
||||
case kml::PredefinedColor::DeepOrange:
|
||||
return MWMBookmarkColorDeepOrange;
|
||||
case kml::PredefinedColor::Gray:
|
||||
return MWMBookmarkColorGray;
|
||||
case kml::PredefinedColor::BlueGray:
|
||||
return MWMBookmarkColorBlueGray;
|
||||
case kml::PredefinedColor::Count:
|
||||
return MWMBookmarkColorCount;
|
||||
MWMBookmarkColor convertKmlColor(kml::PredefinedColor kmlColor)
|
||||
{
|
||||
switch (kmlColor)
|
||||
{
|
||||
case kml::PredefinedColor::None: return MWMBookmarkColorNone;
|
||||
case kml::PredefinedColor::Red: return MWMBookmarkColorRed;
|
||||
case kml::PredefinedColor::Blue: return MWMBookmarkColorBlue;
|
||||
case kml::PredefinedColor::Purple: return MWMBookmarkColorPurple;
|
||||
case kml::PredefinedColor::Yellow: return MWMBookmarkColorYellow;
|
||||
case kml::PredefinedColor::Pink: return MWMBookmarkColorPink;
|
||||
case kml::PredefinedColor::Brown: return MWMBookmarkColorBrown;
|
||||
case kml::PredefinedColor::Green: return MWMBookmarkColorGreen;
|
||||
case kml::PredefinedColor::Orange: return MWMBookmarkColorOrange;
|
||||
case kml::PredefinedColor::DeepPurple: return MWMBookmarkColorDeepPurple;
|
||||
case kml::PredefinedColor::LightBlue: return MWMBookmarkColorLightBlue;
|
||||
case kml::PredefinedColor::Cyan: return MWMBookmarkColorCyan;
|
||||
case kml::PredefinedColor::Teal: return MWMBookmarkColorTeal;
|
||||
case kml::PredefinedColor::Lime: return MWMBookmarkColorLime;
|
||||
case kml::PredefinedColor::DeepOrange: return MWMBookmarkColorDeepOrange;
|
||||
case kml::PredefinedColor::Gray: return MWMBookmarkColorGray;
|
||||
case kml::PredefinedColor::BlueGray: return MWMBookmarkColorBlueGray;
|
||||
case kml::PredefinedColor::Count: return MWMBookmarkColorCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#import "MWMBookmarksManager.h"
|
||||
|
||||
#import "MWMBookmark+Core.h"
|
||||
#import "MWMBookmarksSection.h"
|
||||
#import "MWMBookmarkGroup.h"
|
||||
#import "MWMBookmarksSection.h"
|
||||
#import "MWMCarPlayBookmarkObject.h"
|
||||
#import "MWMTrack+Core.h"
|
||||
#import "RecentlyDeletedCategory+Core.h"
|
||||
@@ -18,81 +18,60 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
static kml::PredefinedColor kmlColorFromBookmarkColor(MWMBookmarkColor bookmarkColor) {
|
||||
switch (bookmarkColor) {
|
||||
case MWMBookmarkColorNone:
|
||||
return kml::PredefinedColor::None;
|
||||
case MWMBookmarkColorRed:
|
||||
return kml::PredefinedColor::Red;
|
||||
case MWMBookmarkColorBlue:
|
||||
return kml::PredefinedColor::Blue;
|
||||
case MWMBookmarkColorPurple:
|
||||
return kml::PredefinedColor::Purple;
|
||||
case MWMBookmarkColorYellow:
|
||||
return kml::PredefinedColor::Yellow;
|
||||
case MWMBookmarkColorPink:
|
||||
return kml::PredefinedColor::Pink;
|
||||
case MWMBookmarkColorBrown:
|
||||
return kml::PredefinedColor::Brown;
|
||||
case MWMBookmarkColorGreen:
|
||||
return kml::PredefinedColor::Green;
|
||||
case MWMBookmarkColorOrange:
|
||||
return kml::PredefinedColor::Orange;
|
||||
case MWMBookmarkColorDeepPurple:
|
||||
return kml::PredefinedColor::DeepPurple;
|
||||
case MWMBookmarkColorLightBlue:
|
||||
return kml::PredefinedColor::LightBlue;
|
||||
case MWMBookmarkColorCyan:
|
||||
return kml::PredefinedColor::Cyan;
|
||||
case MWMBookmarkColorTeal:
|
||||
return kml::PredefinedColor::Teal;
|
||||
case MWMBookmarkColorLime:
|
||||
return kml::PredefinedColor::Lime;
|
||||
case MWMBookmarkColorDeepOrange:
|
||||
return kml::PredefinedColor::DeepOrange;
|
||||
case MWMBookmarkColorGray:
|
||||
return kml::PredefinedColor::Gray;
|
||||
case MWMBookmarkColorBlueGray:
|
||||
return kml::PredefinedColor::BlueGray;
|
||||
case MWMBookmarkColorCount:
|
||||
return kml::PredefinedColor::Count;
|
||||
static kml::PredefinedColor kmlColorFromBookmarkColor(MWMBookmarkColor bookmarkColor)
|
||||
{
|
||||
switch (bookmarkColor)
|
||||
{
|
||||
case MWMBookmarkColorNone: return kml::PredefinedColor::None;
|
||||
case MWMBookmarkColorRed: return kml::PredefinedColor::Red;
|
||||
case MWMBookmarkColorBlue: return kml::PredefinedColor::Blue;
|
||||
case MWMBookmarkColorPurple: return kml::PredefinedColor::Purple;
|
||||
case MWMBookmarkColorYellow: return kml::PredefinedColor::Yellow;
|
||||
case MWMBookmarkColorPink: return kml::PredefinedColor::Pink;
|
||||
case MWMBookmarkColorBrown: return kml::PredefinedColor::Brown;
|
||||
case MWMBookmarkColorGreen: return kml::PredefinedColor::Green;
|
||||
case MWMBookmarkColorOrange: return kml::PredefinedColor::Orange;
|
||||
case MWMBookmarkColorDeepPurple: return kml::PredefinedColor::DeepPurple;
|
||||
case MWMBookmarkColorLightBlue: return kml::PredefinedColor::LightBlue;
|
||||
case MWMBookmarkColorCyan: return kml::PredefinedColor::Cyan;
|
||||
case MWMBookmarkColorTeal: return kml::PredefinedColor::Teal;
|
||||
case MWMBookmarkColorLime: return kml::PredefinedColor::Lime;
|
||||
case MWMBookmarkColorDeepOrange: return kml::PredefinedColor::DeepOrange;
|
||||
case MWMBookmarkColorGray: return kml::PredefinedColor::Gray;
|
||||
case MWMBookmarkColorBlueGray: return kml::PredefinedColor::BlueGray;
|
||||
case MWMBookmarkColorCount: return kml::PredefinedColor::Count;
|
||||
}
|
||||
}
|
||||
|
||||
static MWMBookmarksSortingType convertSortingType(BookmarkManager::SortingType const &sortingType) {
|
||||
switch (sortingType) {
|
||||
case BookmarkManager::SortingType::ByType:
|
||||
return MWMBookmarksSortingTypeByType;
|
||||
case BookmarkManager::SortingType::ByDistance:
|
||||
return MWMBookmarksSortingTypeByDistance;
|
||||
case BookmarkManager::SortingType::ByTime:
|
||||
return MWMBookmarksSortingTypeByTime;
|
||||
case BookmarkManager::SortingType::ByName:
|
||||
return MWMBookmarksSortingTypeByName;
|
||||
static MWMBookmarksSortingType convertSortingType(BookmarkManager::SortingType const & sortingType)
|
||||
{
|
||||
switch (sortingType)
|
||||
{
|
||||
case BookmarkManager::SortingType::ByType: return MWMBookmarksSortingTypeByType;
|
||||
case BookmarkManager::SortingType::ByDistance: return MWMBookmarksSortingTypeByDistance;
|
||||
case BookmarkManager::SortingType::ByTime: return MWMBookmarksSortingTypeByTime;
|
||||
case BookmarkManager::SortingType::ByName: return MWMBookmarksSortingTypeByName;
|
||||
}
|
||||
}
|
||||
|
||||
static BookmarkManager::SortingType convertSortingTypeToCore(MWMBookmarksSortingType sortingType) {
|
||||
switch (sortingType) {
|
||||
case MWMBookmarksSortingTypeByType:
|
||||
return BookmarkManager::SortingType::ByType;
|
||||
case MWMBookmarksSortingTypeByDistance:
|
||||
return BookmarkManager::SortingType::ByDistance;
|
||||
case MWMBookmarksSortingTypeByTime:
|
||||
return BookmarkManager::SortingType::ByTime;
|
||||
case MWMBookmarksSortingTypeByName:
|
||||
return BookmarkManager::SortingType::ByName;
|
||||
static BookmarkManager::SortingType convertSortingTypeToCore(MWMBookmarksSortingType sortingType)
|
||||
{
|
||||
switch (sortingType)
|
||||
{
|
||||
case MWMBookmarksSortingTypeByType: return BookmarkManager::SortingType::ByType;
|
||||
case MWMBookmarksSortingTypeByDistance: return BookmarkManager::SortingType::ByDistance;
|
||||
case MWMBookmarksSortingTypeByTime: return BookmarkManager::SortingType::ByTime;
|
||||
case MWMBookmarksSortingTypeByName: return BookmarkManager::SortingType::ByName;
|
||||
}
|
||||
}
|
||||
|
||||
static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
switch (fileType) {
|
||||
case MWMKmlFileTypeText:
|
||||
return KmlFileType::Text;
|
||||
case MWMKmlFileTypeBinary:
|
||||
return KmlFileType::Binary;
|
||||
case MWMKmlFileTypeGpx:
|
||||
return KmlFileType::Gpx;
|
||||
static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType)
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case MWMKmlFileTypeText: return KmlFileType::Text;
|
||||
case MWMKmlFileTypeBinary: return KmlFileType::Binary;
|
||||
case MWMKmlFileTypeGpx: return KmlFileType::Gpx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +93,7 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
{
|
||||
static MWMBookmarksManager * manager;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
manager = [[self alloc] initManager];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ manager = [[self alloc] initManager]; });
|
||||
return manager;
|
||||
}
|
||||
|
||||
@@ -151,13 +128,12 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
BookmarkManager::AsyncLoadingCallbacks bookmarkCallbacks;
|
||||
{
|
||||
__weak auto wSelf = self;
|
||||
bookmarkCallbacks.m_onStarted = [wSelf]() {
|
||||
wSelf.areBookmarksLoaded = NO;
|
||||
};
|
||||
bookmarkCallbacks.m_onStarted = [wSelf]() { wSelf.areBookmarksLoaded = NO; };
|
||||
}
|
||||
{
|
||||
__weak auto wSelf = self;
|
||||
bookmarkCallbacks.m_onFinished = [wSelf]() {
|
||||
bookmarkCallbacks.m_onFinished = [wSelf]()
|
||||
{
|
||||
__strong auto self = wSelf;
|
||||
if (!self)
|
||||
return;
|
||||
@@ -170,8 +146,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
}
|
||||
{
|
||||
__weak auto wSelf = self;
|
||||
bookmarkCallbacks.m_onFileSuccess = [wSelf](std::string const & filePath,
|
||||
bool isTemporaryFile) {
|
||||
bookmarkCallbacks.m_onFileSuccess = [wSelf](std::string const & filePath, bool isTemporaryFile)
|
||||
{
|
||||
__strong __typeof(self) self = wSelf;
|
||||
[self loopObservers:^(id<MWMBookmarksObserver> observer) {
|
||||
if ([observer respondsToSelector:@selector(onBookmarksFileLoadSuccess)])
|
||||
@@ -181,7 +157,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
}
|
||||
{
|
||||
__weak auto wSelf = self;
|
||||
bookmarkCallbacks.m_onFileError = [wSelf](std::string const & filePath, bool isTemporaryFile) {
|
||||
bookmarkCallbacks.m_onFileError = [wSelf](std::string const & filePath, bool isTemporaryFile)
|
||||
{
|
||||
__strong __typeof(self) self = wSelf;
|
||||
[self loopObservers:^(id<MWMBookmarksObserver> observer) {
|
||||
if ([observer respondsToSelector:@selector(onBookmarksFileLoadError)])
|
||||
@@ -228,11 +205,13 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return self.bm.AreAllCategoriesEmpty();
|
||||
}
|
||||
|
||||
- (BOOL)isCategoryEmpty:(MWMMarkGroupID)groupId {
|
||||
- (BOOL)isCategoryEmpty:(MWMMarkGroupID)groupId
|
||||
{
|
||||
return self.bm.HasBmCategory(groupId) && self.bm.IsCategoryEmpty(groupId);
|
||||
}
|
||||
|
||||
- (void)prepareForSearch:(MWMMarkGroupID)groupId {
|
||||
- (void)prepareForSearch:(MWMMarkGroupID)groupId
|
||||
{
|
||||
self.bm.PrepareForSearch(groupId);
|
||||
}
|
||||
|
||||
@@ -255,22 +234,18 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
{
|
||||
switch (self.bm.GetCategoryData(groupId).m_accessRules)
|
||||
{
|
||||
case kml::AccessRules::Local:
|
||||
return MWMBookmarkGroupAccessStatusLocal;
|
||||
case kml::AccessRules::Public:
|
||||
return MWMBookmarkGroupAccessStatusPublic;
|
||||
case kml::AccessRules::DirectLink:
|
||||
return MWMBookmarkGroupAccessStatusPrivate;
|
||||
case kml::AccessRules::AuthorOnly:
|
||||
return MWMBookmarkGroupAccessStatusAuthorOnly;
|
||||
case kml::AccessRules::Local: return MWMBookmarkGroupAccessStatusLocal;
|
||||
case kml::AccessRules::Public: return MWMBookmarkGroupAccessStatusPublic;
|
||||
case kml::AccessRules::DirectLink: return MWMBookmarkGroupAccessStatusPrivate;
|
||||
case kml::AccessRules::AuthorOnly: return MWMBookmarkGroupAccessStatusAuthorOnly;
|
||||
case kml::AccessRules::P2P:
|
||||
case kml::AccessRules::Paid:
|
||||
case kml::AccessRules::Count:
|
||||
return MWMBookmarkGroupAccessStatusOther;
|
||||
case kml::AccessRules::Count: return MWMBookmarkGroupAccessStatusOther;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)getCategoryAnnotation:(MWMMarkGroupID)groupId {
|
||||
- (NSString *)getCategoryAnnotation:(MWMMarkGroupID)groupId
|
||||
{
|
||||
return @(GetPreferredBookmarkStr(self.bm.GetCategoryData(groupId).m_annotation).c_str());
|
||||
}
|
||||
|
||||
@@ -289,32 +264,33 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return @(self.bm.GetCategoryData(groupId).m_authorId.c_str());
|
||||
}
|
||||
|
||||
- (MWMBookmarkGroupType)getCategoryGroupType:(MWMMarkGroupID)groupId {
|
||||
if (self.bm.IsCompilation(groupId) == false) {
|
||||
- (MWMBookmarkGroupType)getCategoryGroupType:(MWMMarkGroupID)groupId
|
||||
{
|
||||
if (self.bm.IsCompilation(groupId) == false)
|
||||
return MWMBookmarkGroupTypeRoot;
|
||||
}
|
||||
switch (self.bm.GetCompilationType(groupId)) {
|
||||
case kml::CompilationType::Category:
|
||||
return MWMBookmarkGroupTypeCategory;
|
||||
case kml::CompilationType::Collection:
|
||||
return MWMBookmarkGroupTypeCollection;
|
||||
case kml::CompilationType::Day:
|
||||
return MWMBookmarkGroupTypeDay;
|
||||
switch (self.bm.GetCompilationType(groupId))
|
||||
{
|
||||
case kml::CompilationType::Category: return MWMBookmarkGroupTypeCategory;
|
||||
case kml::CompilationType::Collection: return MWMBookmarkGroupTypeCollection;
|
||||
case kml::CompilationType::Day: return MWMBookmarkGroupTypeDay;
|
||||
}
|
||||
return MWMBookmarkGroupTypeRoot;
|
||||
}
|
||||
|
||||
- (nullable NSURL *)getCategoryImageUrl:(MWMMarkGroupID)groupId {
|
||||
- (nullable NSURL *)getCategoryImageUrl:(MWMMarkGroupID)groupId
|
||||
{
|
||||
NSString * urlString = @(self.bm.GetCategoryData(groupId).m_imageUrl.c_str());
|
||||
return [NSURL URLWithString:urlString];
|
||||
}
|
||||
|
||||
- (BOOL)hasExtraInfo:(MWMMarkGroupID)groupId {
|
||||
- (BOOL)hasExtraInfo:(MWMMarkGroupID)groupId
|
||||
{
|
||||
auto data = self.bm.GetCategoryData(groupId);
|
||||
return !data.m_description.empty() || !data.m_annotation.empty();
|
||||
}
|
||||
|
||||
- (BOOL)isHtmlDescription:(MWMMarkGroupID)groupId {
|
||||
- (BOOL)isHtmlDescription:(MWMMarkGroupID)groupId
|
||||
{
|
||||
auto const description = GetPreferredBookmarkStr(self.bm.GetCategoryData(groupId).m_description);
|
||||
return strings::IsHTML(description);
|
||||
}
|
||||
@@ -346,11 +322,13 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
self.bm.GetEditSession().SetIsVisible(groupId, isVisible);
|
||||
}
|
||||
|
||||
- (void)setUserCategoriesVisible:(BOOL)isVisible {
|
||||
- (void)setUserCategoriesVisible:(BOOL)isVisible
|
||||
{
|
||||
self.bm.SetAllCategoriesVisibility(isVisible);
|
||||
}
|
||||
|
||||
- (void)setCatalogCategoriesVisible:(BOOL)isVisible {
|
||||
- (void)setCatalogCategoriesVisible:(BOOL)isVisible
|
||||
{
|
||||
self.bm.SetAllCategoriesVisibility(isVisible);
|
||||
}
|
||||
|
||||
@@ -383,24 +361,27 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return self.bm.HasTrack(trackId);
|
||||
}
|
||||
|
||||
- (NSArray<NSNumber *> *)availableSortingTypes:(MWMMarkGroupID)groupId hasMyPosition:(BOOL)hasMyPosition{
|
||||
- (NSArray<NSNumber *> *)availableSortingTypes:(MWMMarkGroupID)groupId hasMyPosition:(BOOL)hasMyPosition
|
||||
{
|
||||
auto const availableTypes = self.bm.GetAvailableSortingTypes(groupId, hasMyPosition);
|
||||
NSMutableArray * result = [NSMutableArray array];
|
||||
for (auto const &sortingType : availableTypes) {
|
||||
for (auto const & sortingType : availableTypes)
|
||||
[result addObject:[NSNumber numberWithInteger:convertSortingType(sortingType)]];
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
- (void)sortBookmarks:(MWMMarkGroupID)groupId
|
||||
sortingType:(MWMBookmarksSortingType)sortingType
|
||||
location:(CLLocation *)location
|
||||
completion:(SortBookmarksCompletionBlock)completion {
|
||||
completion:(SortBookmarksCompletionBlock)completion
|
||||
{
|
||||
self.bm.SetLastSortingType(groupId, convertSortingTypeToCore(sortingType));
|
||||
m2::PointD myPosition = m2::PointD::Zero();
|
||||
|
||||
if (sortingType == MWMBookmarksSortingTypeByDistance) {
|
||||
if (!location) {
|
||||
if (sortingType == MWMBookmarksSortingTypeByDistance)
|
||||
{
|
||||
if (!location)
|
||||
{
|
||||
completion(nil);
|
||||
return;
|
||||
}
|
||||
@@ -416,30 +397,33 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
sortParams.m_hasMyPosition = location != nil;
|
||||
sortParams.m_myPosition = myPosition;
|
||||
sortParams.m_onResults = [weakSelf, sortId, completion](BookmarkManager::SortedBlocksCollection && sortedBlocks,
|
||||
BookmarkManager::SortParams::Status status) {
|
||||
BookmarkManager::SortParams::Status status)
|
||||
{
|
||||
__strong auto self = weakSelf;
|
||||
if (!self || sortId != self.lastSortId)
|
||||
return;
|
||||
|
||||
switch (status) {
|
||||
case BookmarkManager::SortParams::Status::Completed: {
|
||||
switch (status)
|
||||
{
|
||||
case BookmarkManager::SortParams::Status::Completed:
|
||||
{
|
||||
NSMutableArray * result = [NSMutableArray array];
|
||||
for (auto const &sortedBlock : sortedBlocks) {
|
||||
for (auto const & sortedBlock : sortedBlocks)
|
||||
{
|
||||
NSMutableArray * bookmarks = nil;
|
||||
if (sortedBlock.m_markIds.size() > 0) {
|
||||
if (sortedBlock.m_markIds.size() > 0)
|
||||
{
|
||||
bookmarks = [NSMutableArray array];
|
||||
for (auto const &markId : sortedBlock.m_markIds) {
|
||||
[bookmarks addObject:[[MWMBookmark alloc] initWithMarkId:markId
|
||||
bookmarkData:self.bm.GetBookmark(markId)]];
|
||||
}
|
||||
for (auto const & markId : sortedBlock.m_markIds)
|
||||
[bookmarks addObject:[[MWMBookmark alloc] initWithMarkId:markId bookmarkData:self.bm.GetBookmark(markId)]];
|
||||
}
|
||||
NSMutableArray * tracks = nil;
|
||||
if (sortedBlock.m_trackIds.size() > 0) {
|
||||
if (sortedBlock.m_trackIds.size() > 0)
|
||||
{
|
||||
tracks = [NSMutableArray array];
|
||||
for (auto const &trackId : sortedBlock.m_trackIds) {
|
||||
for (auto const & trackId : sortedBlock.m_trackIds)
|
||||
[tracks addObject:[[MWMTrack alloc] initWithTrackId:trackId trackData:self.bm.GetTrack(trackId)]];
|
||||
}
|
||||
}
|
||||
[result addObject:[[MWMBookmarksSection alloc] initWithTitle:@(sortedBlock.m_blockName.c_str())
|
||||
bookmarks:bookmarks
|
||||
tracks:tracks]];
|
||||
@@ -447,27 +431,28 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
completion([result copy]);
|
||||
break;
|
||||
}
|
||||
case BookmarkManager::SortParams::Status::Cancelled:
|
||||
completion(nil);
|
||||
break;
|
||||
case BookmarkManager::SortParams::Status::Cancelled: completion(nil); break;
|
||||
}
|
||||
};
|
||||
|
||||
self.bm.GetSortedCategory(sortParams);
|
||||
}
|
||||
|
||||
- (BOOL)hasLastSortingType:(MWMMarkGroupID)groupId {
|
||||
- (BOOL)hasLastSortingType:(MWMMarkGroupID)groupId
|
||||
{
|
||||
BookmarkManager::SortingType st;
|
||||
return self.bm.GetLastSortingType(groupId, st);
|
||||
}
|
||||
|
||||
- (MWMBookmarksSortingType)lastSortingType:(MWMMarkGroupID)groupId {
|
||||
- (MWMBookmarksSortingType)lastSortingType:(MWMMarkGroupID)groupId
|
||||
{
|
||||
BookmarkManager::SortingType st;
|
||||
self.bm.GetLastSortingType(groupId, st);
|
||||
return convertSortingType(st);
|
||||
}
|
||||
|
||||
- (void)resetLastSortingType:(MWMMarkGroupID)groupId {
|
||||
- (void)resetLastSortingType:(MWMMarkGroupID)groupId
|
||||
{
|
||||
self.bm.ResetLastSortingType(groupId);
|
||||
}
|
||||
|
||||
@@ -485,7 +470,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
- (MWMMarkIDCollection)bookmarkIdsForCategory:(MWMMarkGroupID)categoryId {
|
||||
- (MWMMarkIDCollection)bookmarkIdsForCategory:(MWMMarkGroupID)categoryId
|
||||
{
|
||||
auto const & bookmarkIds = self.bm.GetUserMarkIds(categoryId);
|
||||
NSMutableArray<NSNumber *> * collection = [[NSMutableArray alloc] initWithCapacity:bookmarkIds.size()];
|
||||
for (auto bookmarkId : bookmarkIds)
|
||||
@@ -502,39 +488,45 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)deleteTrack:(MWMTrackID)trackId {
|
||||
- (void)deleteTrack:(MWMTrackID)trackId
|
||||
{
|
||||
self.bm.GetEditSession().DeleteTrack(trackId);
|
||||
}
|
||||
|
||||
- (MWMBookmark *)bookmarkWithId:(MWMMarkID)bookmarkId {
|
||||
- (MWMBookmark *)bookmarkWithId:(MWMMarkID)bookmarkId
|
||||
{
|
||||
return [[MWMBookmark alloc] initWithMarkId:bookmarkId bookmarkData:self.bm.GetBookmark(bookmarkId)];
|
||||
}
|
||||
|
||||
- (MWMTrack *)trackWithId:(MWMTrackID)trackId {
|
||||
- (MWMTrack *)trackWithId:(MWMTrackID)trackId
|
||||
{
|
||||
return [[MWMTrack alloc] initWithTrackId:trackId trackData:self.bm.GetTrack(trackId)];
|
||||
}
|
||||
|
||||
- (MWMBookmarkGroup *)categoryForBookmarkId:(MWMMarkID)bookmarkId {
|
||||
- (MWMBookmarkGroup *)categoryForBookmarkId:(MWMMarkID)bookmarkId
|
||||
{
|
||||
auto const groupId = self.bm.GetBookmark(bookmarkId)->GetGroupId();
|
||||
return [self categoryWithId:groupId];
|
||||
}
|
||||
|
||||
- (MWMBookmarkGroup *)categoryForTrackId:(MWMTrackID)trackId {
|
||||
- (MWMBookmarkGroup *)categoryForTrackId:(MWMTrackID)trackId
|
||||
{
|
||||
auto const groupId = self.bm.GetTrack(trackId)->GetGroupId();
|
||||
return [self categoryWithId:groupId];
|
||||
}
|
||||
|
||||
- (NSString *)descriptionForBookmarkId:(MWMMarkID)bookmarkId {
|
||||
- (NSString *)descriptionForBookmarkId:(MWMMarkID)bookmarkId
|
||||
{
|
||||
auto const description = self.bm.GetBookmark(bookmarkId)->GetDescription();
|
||||
return [NSString stringWithUTF8String:description.c_str()];
|
||||
}
|
||||
|
||||
- (NSArray<MWMBookmark *> *)bookmarksForGroup:(MWMMarkGroupID)groupId {
|
||||
- (NSArray<MWMBookmark *> *)bookmarksForGroup:(MWMMarkGroupID)groupId
|
||||
{
|
||||
auto const & bookmarkIds = self.bm.GetUserMarkIds(groupId);
|
||||
NSMutableArray * result = [NSMutableArray array];
|
||||
for (auto bookmarkId : bookmarkIds) {
|
||||
for (auto bookmarkId : bookmarkIds)
|
||||
[result addObject:[[MWMBookmark alloc] initWithMarkId:bookmarkId bookmarkData:self.bm.GetBookmark(bookmarkId)]];
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
@@ -547,8 +539,7 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
|
||||
using search::BookmarksSearchParams;
|
||||
BookmarksSearchParams params{
|
||||
text.UTF8String,
|
||||
groupId,
|
||||
text.UTF8String, groupId,
|
||||
// m_onResults
|
||||
[weakSelf, searchId, completion](BookmarksSearchParams::Results results, BookmarksSearchParams::Status status)
|
||||
{
|
||||
@@ -563,16 +554,15 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
[result addObject:[[MWMBookmark alloc] initWithMarkId:bookmarkId bookmarkData:self.bm.GetBookmark(bookmarkId)]];
|
||||
|
||||
completion(result);
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
GetFramework().GetSearchAPI().SearchInBookmarks(std::move(params));
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Tracks
|
||||
|
||||
- (MWMTrackIDCollection)trackIdsForCategory:(MWMMarkGroupID)categoryId {
|
||||
- (MWMTrackIDCollection)trackIdsForCategory:(MWMMarkGroupID)categoryId
|
||||
{
|
||||
auto const & trackIds = self.bm.GetTrackIds(categoryId);
|
||||
NSMutableArray<NSNumber *> * collection = [[NSMutableArray alloc] initWithCapacity:trackIds.size()];
|
||||
|
||||
@@ -581,7 +571,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return collection;
|
||||
}
|
||||
|
||||
- (NSArray<MWMTrack *> *)tracksForGroup:(MWMMarkGroupID)groupId {
|
||||
- (NSArray<MWMTrack *> *)tracksForGroup:(MWMMarkGroupID)groupId
|
||||
{
|
||||
auto const & trackIds = self.bm.GetTrackIds(groupId);
|
||||
NSMutableArray * result = [[NSMutableArray alloc] initWithCapacity:trackIds.size()];
|
||||
|
||||
@@ -590,7 +581,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSArray<MWMBookmarkGroup *> *)collectionsForGroup:(MWMMarkGroupID)groupId {
|
||||
- (NSArray<MWMBookmarkGroup *> *)collectionsForGroup:(MWMMarkGroupID)groupId
|
||||
{
|
||||
auto const & collectionIds = self.bm.GetChildrenCollections(groupId);
|
||||
NSMutableArray * result = [[NSMutableArray alloc] initWithCapacity:collectionIds.size()];
|
||||
|
||||
@@ -599,7 +591,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSArray<MWMBookmarkGroup *> *)categoriesForGroup:(MWMMarkGroupID)groupId {
|
||||
- (NSArray<MWMBookmarkGroup *> *)categoriesForGroup:(MWMMarkGroupID)groupId
|
||||
{
|
||||
auto const & categoryIds = self.bm.GetChildrenCategories(groupId);
|
||||
NSMutableArray * result = [[NSMutableArray alloc] initWithCapacity:categoryIds.size()];
|
||||
|
||||
@@ -610,48 +603,50 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
|
||||
#pragma mark - Category sharing
|
||||
|
||||
- (void)shareCategory:(MWMMarkGroupID)groupId fileType:(MWMKmlFileType)fileType completion:(SharingResultCompletionHandler)completion {
|
||||
self.bm.PrepareFileForSharing({groupId}, [self, completion](auto sharingResult) {
|
||||
[self handleSharingResult:sharingResult completion:completion];
|
||||
}, convertFileTypeToCore(fileType));
|
||||
- (void)shareCategory:(MWMMarkGroupID)groupId
|
||||
fileType:(MWMKmlFileType)fileType
|
||||
completion:(SharingResultCompletionHandler)completion
|
||||
{
|
||||
self.bm.PrepareFileForSharing({groupId}, [self, completion](auto sharingResult)
|
||||
{ [self handleSharingResult:sharingResult completion:completion]; }, convertFileTypeToCore(fileType));
|
||||
}
|
||||
|
||||
- (void)shareAllCategoriesWithCompletion:(SharingResultCompletionHandler)completion {
|
||||
self.bm.PrepareAllFilesForSharing([self, completion](auto sharingResult) {
|
||||
[self handleSharingResult:sharingResult completion:completion];
|
||||
});
|
||||
- (void)shareAllCategoriesWithCompletion:(SharingResultCompletionHandler)completion
|
||||
{
|
||||
self.bm.PrepareAllFilesForSharing([self, completion](auto sharingResult)
|
||||
{ [self handleSharingResult:sharingResult completion:completion]; });
|
||||
}
|
||||
|
||||
- (void)shareTrack:(MWMTrackID)trackId fileType:(MWMKmlFileType)fileType completion:(SharingResultCompletionHandler)completion {
|
||||
self.bm.PrepareTrackFileForSharing(trackId, [self, completion](auto sharingResult) {
|
||||
[self handleSharingResult:sharingResult completion:completion];
|
||||
}, convertFileTypeToCore(fileType));
|
||||
- (void)shareTrack:(MWMTrackID)trackId
|
||||
fileType:(MWMKmlFileType)fileType
|
||||
completion:(SharingResultCompletionHandler)completion
|
||||
{
|
||||
self.bm.PrepareTrackFileForSharing(trackId, [self, completion](auto sharingResult)
|
||||
{ [self handleSharingResult:sharingResult completion:completion]; }, convertFileTypeToCore(fileType));
|
||||
}
|
||||
|
||||
- (void)handleSharingResult:(BookmarkManager::SharingResult)sharingResult completion:(SharingResultCompletionHandler)completion {
|
||||
- (void)handleSharingResult:(BookmarkManager::SharingResult)sharingResult
|
||||
completion:(SharingResultCompletionHandler)completion
|
||||
{
|
||||
NSURL * urlToALocalFile = nil;
|
||||
MWMBookmarksShareStatus status;
|
||||
switch (sharingResult.m_code) {
|
||||
switch (sharingResult.m_code)
|
||||
{
|
||||
case BookmarkManager::SharingResult::Code::Success:
|
||||
urlToALocalFile = [NSURL fileURLWithPath:@(sharingResult.m_sharingPath.c_str()) isDirectory:NO];
|
||||
ASSERT(urlToALocalFile, ("Invalid share category URL"));
|
||||
self.shareCategoryURL = urlToALocalFile;
|
||||
status = MWMBookmarksShareStatusSuccess;
|
||||
break;
|
||||
case BookmarkManager::SharingResult::Code::EmptyCategory:
|
||||
status = MWMBookmarksShareStatusEmptyCategory;
|
||||
break;
|
||||
case BookmarkManager::SharingResult::Code::ArchiveError:
|
||||
status = MWMBookmarksShareStatusArchiveError;
|
||||
break;
|
||||
case BookmarkManager::SharingResult::Code::FileError:
|
||||
status = MWMBookmarksShareStatusFileError;
|
||||
break;
|
||||
case BookmarkManager::SharingResult::Code::EmptyCategory: status = MWMBookmarksShareStatusEmptyCategory; break;
|
||||
case BookmarkManager::SharingResult::Code::ArchiveError: status = MWMBookmarksShareStatusArchiveError; break;
|
||||
case BookmarkManager::SharingResult::Code::FileError: status = MWMBookmarksShareStatusFileError; break;
|
||||
}
|
||||
completion(status, urlToALocalFile);
|
||||
}
|
||||
|
||||
- (void)finishSharing {
|
||||
- (void)finishSharing
|
||||
{
|
||||
if (!self.shareCategoryURL)
|
||||
return;
|
||||
|
||||
@@ -661,17 +656,20 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
|
||||
#pragma mark - Notifications
|
||||
|
||||
- (void)setNotificationsEnabled:(BOOL)enabled {
|
||||
- (void)setNotificationsEnabled:(BOOL)enabled
|
||||
{
|
||||
self.bm.SetNotificationsEnabled(enabled);
|
||||
}
|
||||
|
||||
- (BOOL)areNotificationsEnabled {
|
||||
- (BOOL)areNotificationsEnabled
|
||||
{
|
||||
return self.bm.AreNotificationsEnabled();
|
||||
}
|
||||
|
||||
#pragma mark - Catalog
|
||||
|
||||
- (NSArray<MWMBookmarkGroup *> *)sortedUserCategories {
|
||||
- (NSArray<MWMBookmarkGroup *> *)sortedUserCategories
|
||||
{
|
||||
auto const & list = self.bm.GetSortedBmGroupIdList();
|
||||
NSMutableArray<MWMBookmarkGroup *> * result = [[NSMutableArray alloc] initWithCapacity:list.size()];
|
||||
|
||||
@@ -680,11 +678,13 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
return result;
|
||||
}
|
||||
|
||||
- (MWMBookmarkGroup *)categoryWithId:(MWMMarkGroupID)groupId {
|
||||
- (MWMBookmarkGroup *)categoryWithId:(MWMMarkGroupID)groupId
|
||||
{
|
||||
return [[MWMBookmarkGroup alloc] initWithCategoryId:groupId bookmarksManager:self];
|
||||
}
|
||||
|
||||
- (size_t)userCategoriesCount {
|
||||
- (size_t)userCategoriesCount
|
||||
{
|
||||
return self.bm.GetBmGroupsCount();
|
||||
}
|
||||
|
||||
@@ -692,7 +692,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
setGroupId:(MWMMarkGroupID)groupId
|
||||
title:(NSString *)title
|
||||
color:(MWMBookmarkColor)color
|
||||
description:(NSString *)description {
|
||||
description:(NSString *)description
|
||||
{
|
||||
ASSERT_NOT_EQUAL(groupId, kml::kInvalidMarkGroupId, ());
|
||||
auto const currentGroupId = self.bm.GetBookmark(bookmarkId)->GetGroupId();
|
||||
auto editSession = self.bm.GetEditSession();
|
||||
@@ -712,7 +713,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
bookmark->SetCustomName(title.UTF8String);
|
||||
}
|
||||
|
||||
- (void)updateBookmark:(MWMMarkID)bookmarkId setColor:(MWMBookmarkColor)color {
|
||||
- (void)updateBookmark:(MWMMarkID)bookmarkId setColor:(MWMBookmarkColor)color
|
||||
{
|
||||
auto editSession = self.bm.GetEditSession();
|
||||
|
||||
auto bookmark = editSession.GetBookmarkForEdit(bookmarkId);
|
||||
@@ -725,10 +727,12 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
bookmark->SetColor(kmlColor);
|
||||
}
|
||||
|
||||
- (void)moveBookmark:(MWMMarkID)bookmarkId toGroupId:(MWMMarkGroupID)groupId {
|
||||
- (void)moveBookmark:(MWMMarkID)bookmarkId toGroupId:(MWMMarkGroupID)groupId
|
||||
{
|
||||
ASSERT_NOT_EQUAL(groupId, kml::kInvalidMarkGroupId, ());
|
||||
auto const currentGroupId = self.bm.GetBookmark(bookmarkId)->GetGroupId();
|
||||
if (currentGroupId != groupId) {
|
||||
if (currentGroupId != groupId)
|
||||
{
|
||||
auto editSession = self.bm.GetEditSession();
|
||||
editSession.MoveBookmark(bookmarkId, currentGroupId, groupId);
|
||||
}
|
||||
@@ -737,7 +741,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
- (void)updateTrack:(MWMTrackID)trackId
|
||||
setGroupId:(MWMMarkGroupID)groupId
|
||||
color:(UIColor *)color
|
||||
title:(NSString *)title {
|
||||
title:(NSString *)title
|
||||
{
|
||||
ASSERT_NOT_EQUAL(groupId, kml::kInvalidMarkGroupId, ());
|
||||
auto const currentGroupId = self.bm.GetTrack(trackId)->GetGroupId();
|
||||
auto editSession = self.bm.GetEditSession();
|
||||
@@ -756,7 +761,8 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
track->SetName(title.UTF8String);
|
||||
}
|
||||
|
||||
- (void)updateTrack:(MWMTrackID)trackId setColor:(UIColor *)color {
|
||||
- (void)updateTrack:(MWMTrackID)trackId setColor:(UIColor *)color
|
||||
{
|
||||
auto editSession = self.bm.GetEditSession();
|
||||
|
||||
auto track = editSession.GetTrackForEdit(trackId);
|
||||
@@ -769,16 +775,19 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
track->SetColor(newColor);
|
||||
}
|
||||
|
||||
- (void)moveTrack:(MWMTrackID)trackId toGroupId:(MWMMarkGroupID)groupId {
|
||||
- (void)moveTrack:(MWMTrackID)trackId toGroupId:(MWMMarkGroupID)groupId
|
||||
{
|
||||
ASSERT_NOT_EQUAL(groupId, kml::kInvalidMarkGroupId, ());
|
||||
auto const currentGroupId = self.bm.GetTrack(trackId)->GetGroupId();
|
||||
if (currentGroupId != groupId) {
|
||||
if (currentGroupId != groupId)
|
||||
{
|
||||
auto editSession = self.bm.GetEditSession();
|
||||
editSession.MoveTrack(trackId, currentGroupId, groupId);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasRecentlyDeletedBookmark {
|
||||
- (BOOL)hasRecentlyDeletedBookmark
|
||||
{
|
||||
return self.bm.HasRecentlyDeletedBookmark();
|
||||
}
|
||||
|
||||
@@ -795,30 +804,37 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
}
|
||||
|
||||
// MARK: - RecentlyDeletedCategoriesManager
|
||||
- (uint64_t)recentlyDeletedCategoriesCount {
|
||||
- (uint64_t)recentlyDeletedCategoriesCount
|
||||
{
|
||||
return self.bm.GetRecentlyDeletedCategoriesCount();
|
||||
}
|
||||
|
||||
- (NSArray<RecentlyDeletedCategory *> *)getRecentlyDeletedCategories {
|
||||
- (NSArray<RecentlyDeletedCategory *> *)getRecentlyDeletedCategories
|
||||
{
|
||||
auto const categoriesCollection = self.bm.GetRecentlyDeletedCategories();
|
||||
NSMutableArray<RecentlyDeletedCategory *> * recentlyDeletedCategories = [[NSMutableArray alloc] initWithCapacity:categoriesCollection->size()];
|
||||
NSMutableArray<RecentlyDeletedCategory *> * recentlyDeletedCategories =
|
||||
[[NSMutableArray alloc] initWithCapacity:categoriesCollection->size()];
|
||||
|
||||
for (auto const & [filePath, categoryPtr] : * categoriesCollection) {
|
||||
for (auto const & [filePath, categoryPtr] : *categoriesCollection)
|
||||
{
|
||||
ASSERT(categoryPtr, ("Recently deleted category shouldn't be nil."));
|
||||
RecentlyDeletedCategory * category = [[RecentlyDeletedCategory alloc] initWithCategoryData:categoryPtr->m_categoryData filePath:filePath];
|
||||
RecentlyDeletedCategory * category =
|
||||
[[RecentlyDeletedCategory alloc] initWithCategoryData:categoryPtr->m_categoryData filePath:filePath];
|
||||
[recentlyDeletedCategories addObject:category];
|
||||
}
|
||||
return recentlyDeletedCategories;
|
||||
}
|
||||
|
||||
- (void)deleteRecentlyDeletedCategoryAtURLs:(NSArray<NSURL *> *)urls {
|
||||
- (void)deleteRecentlyDeletedCategoryAtURLs:(NSArray<NSURL *> *)urls
|
||||
{
|
||||
std::vector<std::string> filePaths;
|
||||
for (NSURL * url in urls)
|
||||
filePaths.push_back(url.filePathURL.path.UTF8String);
|
||||
self.bm.DeleteRecentlyDeletedCategoriesAtPaths(filePaths);
|
||||
}
|
||||
|
||||
- (void)recoverRecentlyDeletedCategoriesAtURLs:(NSArray<NSURL *> *)urls {
|
||||
- (void)recoverRecentlyDeletedCategoriesAtURLs:(NSArray<NSURL *> *)urls
|
||||
{
|
||||
std::vector<std::string> filePaths;
|
||||
for (NSURL * url in urls)
|
||||
filePaths.push_back(url.filePathURL.path.UTF8String);
|
||||
@@ -830,51 +846,54 @@ static KmlFileType convertFileTypeToCore(MWMKmlFileType fileType) {
|
||||
- (void)loopObservers:(void (^)(id<MWMBookmarksObserver> observer))block
|
||||
{
|
||||
for (id<MWMBookmarksObserver> observer in [self.observers copy])
|
||||
{
|
||||
if (observer)
|
||||
block(observer);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setElevationActivePoint:(CLLocationCoordinate2D)point distance:(double)distance trackId:(uint64_t)trackId {
|
||||
- (void)setElevationActivePoint:(CLLocationCoordinate2D)point distance:(double)distance trackId:(uint64_t)trackId
|
||||
{
|
||||
self.bm.SetElevationActivePoint(trackId, mercator::FromLatLon(point.latitude, point.longitude), distance);
|
||||
}
|
||||
|
||||
- (void)setElevationActivePointChanged:(uint64_t)trackId callback:(ElevationPointChangedBlock)callback {
|
||||
- (void)setElevationActivePointChanged:(uint64_t)trackId callback:(ElevationPointChangedBlock)callback
|
||||
{
|
||||
__weak __typeof(self) ws = self;
|
||||
self.bm.SetElevationActivePointChangedCallback([callback, trackId, ws] () {
|
||||
callback(ws.bm.GetElevationActivePoint(trackId));
|
||||
});
|
||||
self.bm.SetElevationActivePointChangedCallback([callback, trackId, ws]()
|
||||
{ callback(ws.bm.GetElevationActivePoint(trackId)); });
|
||||
}
|
||||
|
||||
- (void)resetElevationActivePointChanged {
|
||||
- (void)resetElevationActivePointChanged
|
||||
{
|
||||
self.bm.SetElevationActivePointChangedCallback(nullptr);
|
||||
}
|
||||
|
||||
- (void)setElevationMyPositionChanged:(uint64_t)trackId callback:(ElevationPointChangedBlock)callback {
|
||||
- (void)setElevationMyPositionChanged:(uint64_t)trackId callback:(ElevationPointChangedBlock)callback
|
||||
{
|
||||
__weak __typeof(self) ws = self;
|
||||
self.bm.SetElevationMyPositionChangedCallback([callback, trackId, ws] () {
|
||||
callback(ws.bm.GetElevationMyPosition(trackId));
|
||||
});
|
||||
self.bm.SetElevationMyPositionChangedCallback([callback, trackId, ws]()
|
||||
{ callback(ws.bm.GetElevationMyPosition(trackId)); });
|
||||
}
|
||||
|
||||
- (void)resetElevationMyPositionChanged {
|
||||
- (void)resetElevationMyPositionChanged
|
||||
{
|
||||
self.bm.SetElevationMyPositionChangedCallback(nullptr);
|
||||
}
|
||||
|
||||
+ (dp::Color)getColorFromUIColor:(UIColor *)color {
|
||||
+ (dp::Color)getColorFromUIColor:(UIColor *)color
|
||||
{
|
||||
CGFloat fRed, fGreen, fBlue, fAlpha;
|
||||
[color getRed:&fRed green:&fGreen blue:&fBlue alpha:&fAlpha];
|
||||
|
||||
const uint8_t red = [self convertColorComponentToHex:fRed];
|
||||
const uint8_t green = [self convertColorComponentToHex:fGreen];
|
||||
const uint8_t blue = [self convertColorComponentToHex:fBlue];
|
||||
const uint8_t alpha = [self convertColorComponentToHex:fAlpha];
|
||||
uint8_t const red = [self convertColorComponentToHex:fRed];
|
||||
uint8_t const green = [self convertColorComponentToHex:fGreen];
|
||||
uint8_t const blue = [self convertColorComponentToHex:fBlue];
|
||||
uint8_t const alpha = [self convertColorComponentToHex:fAlpha];
|
||||
|
||||
return dp::Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
+ (uint8_t)convertColorComponentToHex:(CGFloat)color {
|
||||
+ (uint8_t)convertColorComponentToHex:(CGFloat)color
|
||||
{
|
||||
ASSERT_LESS_OR_EQUAL(color, 1.f, ("Extended sRGB color space is not supported"));
|
||||
ASSERT_GREATER_OR_EQUAL(color, 0.f, ("Extended sRGB color space is not supported"));
|
||||
static constexpr uint8_t kMaxChannelValue = 255;
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
@implementation MWMCarPlayBookmarkObject
|
||||
|
||||
- (instancetype)initWithBookmarkId:(MWMMarkID)bookmarkId {
|
||||
- (instancetype)initWithBookmarkId:(MWMMarkID)bookmarkId
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
self.bookmarkId = bookmarkId;
|
||||
auto const & bm = GetFramework().GetBookmarkManager();
|
||||
Bookmark const * bookmark = bm.GetBookmark(bookmarkId);
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
@implementation MWMTrack (Core)
|
||||
|
||||
- (instancetype)initWithTrackId:(MWMTrackID)trackId trackData:(Track const *)track {
|
||||
- (instancetype)initWithTrackId:(MWMTrackID)trackId trackData:(Track const *)track
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_trackId = trackId;
|
||||
_trackName = @(track->GetName().c_str());
|
||||
_trackLengthMeters = track->GetLengthMeters();
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#import "RecentlyDeletedCategory+Core.h"
|
||||
|
||||
#include <map/bookmark_helpers.hpp>
|
||||
#include <platform/platform_ios.h>
|
||||
#include <map/bookmark_helpers.hpp>
|
||||
|
||||
@implementation RecentlyDeletedCategory
|
||||
|
||||
- (instancetype)initTitle:(NSString *)title fileURL:(NSURL *)fileURL deletionDate:(NSDate *)deletionDate {
|
||||
- (instancetype)initTitle:(NSString *)title fileURL:(NSURL *)fileURL deletionDate:(NSDate *)deletionDate
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_title = title;
|
||||
_fileURL = fileURL;
|
||||
_deletionDate = deletionDate;
|
||||
@@ -19,9 +21,11 @@
|
||||
|
||||
@implementation RecentlyDeletedCategory (Core)
|
||||
|
||||
- (instancetype)initWithCategoryData:(kml::CategoryData)data filePath:(std::string const &)filePath {
|
||||
- (instancetype)initWithCategoryData:(kml::CategoryData)data filePath:(std::string const &)filePath
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
auto const name = GetPreferredBookmarkStr(data.m_name);
|
||||
_title = [NSString stringWithCString:name.c_str() encoding:NSUTF8StringEncoding];
|
||||
auto const pathString = [NSString stringWithCString:filePath.c_str() encoding:NSUTF8StringEncoding];
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#import "TrackInfo+Core.h"
|
||||
#import "StringUtils.h"
|
||||
#import "TrackInfo+Core.h"
|
||||
|
||||
@implementation TrackInfo
|
||||
|
||||
+ (TrackInfo *)emptyInfo {
|
||||
+ (TrackInfo *)emptyInfo
|
||||
{
|
||||
return [[TrackInfo alloc] initWithTrackStatistics:TrackStatistics()];
|
||||
}
|
||||
|
||||
@@ -11,17 +12,17 @@
|
||||
|
||||
@implementation TrackInfo (Core)
|
||||
|
||||
- (instancetype)initWithTrackStatistics:(TrackStatistics const &)statistics {
|
||||
if (self = [super init]) {
|
||||
- (instancetype)initWithTrackStatistics:(TrackStatistics const &)statistics
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_distance = ToNSString(statistics.GetFormattedLength());
|
||||
_duration = ToNSString(statistics.GetFormattedDuration());
|
||||
_ascent = ToNSString(statistics.GetFormattedAscent());
|
||||
_descent = ToNSString(statistics.GetFormattedDescent());
|
||||
_maxElevation = ToNSString(statistics.GetFormattedMaxElevation());
|
||||
_minElevation = ToNSString(statistics.GetFormattedMinElevation());
|
||||
_hasElevationInfo = statistics.m_ascent != 0 ||
|
||||
statistics.m_descent != 0 ||
|
||||
statistics.m_maxElevation != 0 ||
|
||||
_hasElevationInfo = statistics.m_ascent != 0 || statistics.m_descent != 0 || statistics.m_maxElevation != 0 ||
|
||||
statistics.m_minElevation != 0;
|
||||
}
|
||||
return self;
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
{
|
||||
static AppInfo * appInfo;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
appInfo = [[self alloc] init];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ appInfo = [[self alloc] init]; });
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
@@ -94,7 +92,8 @@
|
||||
NSURL * telURL = [NSURL URLWithString:@"tel://"];
|
||||
if (![UIApplication.sharedApplication canOpenURL:telURL])
|
||||
return NO;
|
||||
NSDictionary<NSString *,CTCarrier *> * dict = [[CTTelephonyNetworkInfo alloc] init].serviceSubscriberCellularProviders;
|
||||
NSDictionary<NSString *, CTCarrier *> * dict =
|
||||
[[CTTelephonyNetworkInfo alloc] init].serviceSubscriberCellularProviders;
|
||||
for (id key in dict)
|
||||
{
|
||||
NSString * networkCode = [dict objectForKey:key].mobileNetworkCode;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#import "MWMGeoUtil.h"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/angles.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "platform/locale.hpp"
|
||||
#include "platform/localization.hpp"
|
||||
#include "platform/settings.hpp"
|
||||
#include "platform/measurement_utils.hpp"
|
||||
#include "platform/settings.hpp"
|
||||
|
||||
@implementation Measure
|
||||
|
||||
@@ -31,14 +31,17 @@
|
||||
let speedString = formatter.string(from: speedMeasurement)
|
||||
*/
|
||||
|
||||
- (NSString*) valueAsString {
|
||||
- (NSString *)valueAsString
|
||||
{
|
||||
auto const outString = measurement_utils::ToStringPrecision(self.value, self.value >= 10.0 ? 0 : 1);
|
||||
return [NSString stringWithUTF8String:outString.c_str()];
|
||||
}
|
||||
|
||||
- (instancetype)initAsSpeed:(double) mps {
|
||||
- (instancetype)initAsSpeed:(double)mps
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
auto units = measurement_utils::Units::Metric;
|
||||
settings::TryGet(settings::kMeasurementUnits, units);
|
||||
_value = measurement_utils::MpsToUnits(mps, units);
|
||||
@@ -52,13 +55,15 @@
|
||||
|
||||
@implementation MWMGeoUtil
|
||||
|
||||
+ (float)angleAtPoint:(CLLocationCoordinate2D)p1 toPoint:(CLLocationCoordinate2D)p2 {
|
||||
+ (float)angleAtPoint:(CLLocationCoordinate2D)p1 toPoint:(CLLocationCoordinate2D)p2
|
||||
{
|
||||
auto mp1 = mercator::FromLatLon(p1.latitude, p1.longitude);
|
||||
auto mp2 = mercator::FromLatLon(p2.latitude, p2.longitude);
|
||||
return ang::AngleTo(mp1, mp2);
|
||||
}
|
||||
|
||||
+ (NSString *)formattedOsmLinkForCoordinate:(CLLocationCoordinate2D)coordinate zoomLevel:(int)zoomLevel {
|
||||
+ (NSString *)formattedOsmLinkForCoordinate:(CLLocationCoordinate2D)coordinate zoomLevel:(int)zoomLevel
|
||||
{
|
||||
auto const link = measurement_utils::FormatOsmLink(coordinate.latitude, coordinate.longitude, zoomLevel);
|
||||
return [NSString stringWithCString:link.c_str() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ static inline InAppFeatureHighlightType FeatureTypeFrom(url_scheme::InAppFeature
|
||||
|
||||
@implementation DeepLinkInAppFeatureHighlightData
|
||||
|
||||
- (instancetype)init:(DeeplinkUrlType)urlType {
|
||||
- (instancetype)init:(DeeplinkUrlType)urlType
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_urlType = urlType;
|
||||
_feature = FeatureTypeFrom(GetFramework().GetInAppFeatureHighlightRequest().m_feature);
|
||||
}
|
||||
|
||||
@@ -22,16 +22,19 @@ static inline DeeplinkUrlType deeplinkUrlType(url_scheme::ParsedMapApi::UrlType
|
||||
|
||||
@implementation DeepLinkParser
|
||||
|
||||
+ (DeeplinkUrlType)parseAndSetApiURL:(NSURL *)url {
|
||||
+ (DeeplinkUrlType)parseAndSetApiURL:(NSURL *)url
|
||||
{
|
||||
Framework & f = GetFramework();
|
||||
return deeplinkUrlType(f.ParseAndSetApiURL(url.absoluteString.UTF8String));
|
||||
}
|
||||
|
||||
+ (void)executeMapApiRequest {
|
||||
+ (void)executeMapApiRequest
|
||||
{
|
||||
GetFramework().ExecuteMapApiRequest();
|
||||
}
|
||||
|
||||
+ (void)addBookmarksFile:(NSURL *)url {
|
||||
+ (void)addBookmarksFile:(NSURL *)url
|
||||
{
|
||||
// iOS doesn't create temporary files on import at least in Safari and Files.
|
||||
GetFramework().AddBookmarksFile(url.path.UTF8String, false /* isTemporaryFile */);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#import "DeepLinkSearchData.h"
|
||||
#import <CoreApi/Framework.h>
|
||||
#include "drape_frontend/visual_params.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/latlon.hpp"
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
@implementation DeepLinkSearchData
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
auto const & request = GetFramework().GetParsedSearchRequest();
|
||||
ms::LatLon const center = GetFramework().GetParsedCenterLatLon();
|
||||
_query = [@((request.m_query + " ").c_str()) stringByRemovingPercentEncoding];
|
||||
@@ -19,11 +21,13 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)hasValidCenterLatLon {
|
||||
- (BOOL)hasValidCenterLatLon
|
||||
{
|
||||
return _centerLat != ms::LatLon::kInvalid && _centerLon != ms::LatLon::kInvalid;
|
||||
}
|
||||
|
||||
- (void)onViewportChanged:(int)zoomLevel {
|
||||
- (void)onViewportChanged:(int)zoomLevel
|
||||
{
|
||||
auto const center = mercator::FromLatLon(_centerLat, _centerLon);
|
||||
auto const rect = df::GetRectForDrawScale(zoomLevel, center);
|
||||
GetFramework().GetSearchAPI().OnViewportChanged(rect);
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
@implementation AltitudeFormatter
|
||||
|
||||
+ (NSString *)altitudeStringFromMeters:(double)meters {
|
||||
+ (NSString *)altitudeStringFromMeters:(double)meters
|
||||
{
|
||||
auto const altitude = platform::Distance::FormatAltitude(meters);
|
||||
return [NSString stringWithUTF8String:altitude.c_str()];
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
@implementation DistanceFormatter
|
||||
|
||||
+ (NSString *)distanceStringFromMeters:(double)meters {
|
||||
+ (NSString *)distanceStringFromMeters:(double)meters
|
||||
{
|
||||
auto const coreDistance = platform::Distance::CreateFormatted(meters);
|
||||
return [NSString stringWithUTF8String:coreDistance.ToString().c_str()];
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
@implementation DurationFormatter
|
||||
|
||||
+ (NSString *)durationStringFromTimeInterval:(NSTimeInterval)timeInterval {
|
||||
+ (NSString *)durationStringFromTimeInterval:(NSTimeInterval)timeInterval
|
||||
{
|
||||
auto const duration = platform::Duration(static_cast<int>(timeInterval));
|
||||
return [NSString stringWithCString:duration.GetPlatformLocalizedString().c_str() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "MWMFrameworkHelper.h"
|
||||
#import "ElevationProfileData+Core.h"
|
||||
#import "MWMMapSearchResult+Core.h"
|
||||
#import "TrackInfo+Core.h"
|
||||
#import "ElevationProfileData+Core.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
@implementation MWMFrameworkHelper
|
||||
|
||||
+ (void)processFirstLaunch:(BOOL)hasLocation {
|
||||
+ (void)processFirstLaunch:(BOOL)hasLocation
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
if (!hasLocation)
|
||||
f.SwitchMyPositionNextMode();
|
||||
@@ -20,7 +21,8 @@
|
||||
f.RunFirstLaunchAnimation();
|
||||
}
|
||||
|
||||
+ (void)setVisibleViewport:(CGRect)rect scaleFactor:(CGFloat)scale {
|
||||
+ (void)setVisibleViewport:(CGRect)rect scaleFactor:(CGFloat)scale
|
||||
{
|
||||
CGFloat const x0 = rect.origin.x * scale;
|
||||
CGFloat const y0 = rect.origin.y * scale;
|
||||
CGFloat const x1 = x0 + rect.size.width * scale;
|
||||
@@ -28,32 +30,27 @@
|
||||
GetFramework().SetVisibleViewport(m2::RectD(x0, y0, x1, y1));
|
||||
}
|
||||
|
||||
+ (void)setTheme:(MWMTheme)theme {
|
||||
+ (void)setTheme:(MWMTheme)theme
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
|
||||
auto const style = f.GetMapStyle();
|
||||
auto const isOutdoor = ^BOOL(MapStyle style) {
|
||||
switch (style) {
|
||||
switch (style)
|
||||
{
|
||||
case MapStyleOutdoorsLight:
|
||||
case MapStyleOutdoorsDark:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
case MapStyleOutdoorsDark: return YES;
|
||||
default: return NO;
|
||||
}
|
||||
}(style);
|
||||
auto const newStyle = ^MapStyle(MWMTheme theme) {
|
||||
switch (theme) {
|
||||
case MWMThemeDay:
|
||||
return isOutdoor ? MapStyleOutdoorsLight : MapStyleDefaultLight;
|
||||
case MWMThemeVehicleDay:
|
||||
return MapStyleVehicleLight;
|
||||
case MWMThemeNight:
|
||||
return isOutdoor ? MapStyleOutdoorsDark : MapStyleDefaultDark;
|
||||
case MWMThemeVehicleNight:
|
||||
return MapStyleVehicleDark;
|
||||
case MWMThemeAuto:
|
||||
NSAssert(NO, @"Invalid theme");
|
||||
return MapStyleDefaultLight;
|
||||
switch (theme)
|
||||
{
|
||||
case MWMThemeDay: return isOutdoor ? MapStyleOutdoorsLight : MapStyleDefaultLight;
|
||||
case MWMThemeVehicleDay: return MapStyleVehicleLight;
|
||||
case MWMThemeNight: return isOutdoor ? MapStyleOutdoorsDark : MapStyleDefaultDark;
|
||||
case MWMThemeVehicleNight: return MapStyleVehicleDark;
|
||||
case MWMThemeAuto: NSAssert(NO, @"Invalid theme"); return MapStyleDefaultLight;
|
||||
}
|
||||
}(theme);
|
||||
|
||||
@@ -61,93 +58,101 @@
|
||||
f.SetMapStyle(newStyle);
|
||||
}
|
||||
|
||||
+ (MWMDayTime)daytimeAtLocation:(CLLocation *)location {
|
||||
+ (MWMDayTime)daytimeAtLocation:(CLLocation *)location
|
||||
{
|
||||
if (!location)
|
||||
return MWMDayTimeDay;
|
||||
DayTimeType dayTime =
|
||||
GetDayTime(NSDate.date.timeIntervalSince1970, location.coordinate.latitude, location.coordinate.longitude);
|
||||
switch (dayTime) {
|
||||
switch (dayTime)
|
||||
{
|
||||
case DayTimeType::Day:
|
||||
case DayTimeType::PolarDay:
|
||||
return MWMDayTimeDay;
|
||||
case DayTimeType::PolarDay: return MWMDayTimeDay;
|
||||
case DayTimeType::Night:
|
||||
case DayTimeType::PolarNight:
|
||||
return MWMDayTimeNight;
|
||||
case DayTimeType::PolarNight: return MWMDayTimeNight;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)createFramework {
|
||||
+ (void)createFramework
|
||||
{
|
||||
UNUSED_VALUE(GetFramework());
|
||||
}
|
||||
|
||||
+ (MWMMarkID)invalidBookmarkId {
|
||||
+ (MWMMarkID)invalidBookmarkId
|
||||
{
|
||||
return kml::kInvalidMarkId;
|
||||
}
|
||||
|
||||
+ (MWMMarkGroupID)invalidCategoryId {
|
||||
+ (MWMMarkGroupID)invalidCategoryId
|
||||
{
|
||||
return kml::kInvalidMarkGroupId;
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)obtainLastSearchQueries {
|
||||
+ (NSArray<NSString *> *)obtainLastSearchQueries
|
||||
{
|
||||
NSMutableArray * result = [NSMutableArray array];
|
||||
auto const & queries = GetFramework().GetSearchAPI().GetLastSearchQueries();
|
||||
for (auto const &item : queries) {
|
||||
for (auto const & item : queries)
|
||||
[result addObject:@(item.second.c_str())];
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
#pragma mark - Map Interaction
|
||||
|
||||
+ (void)zoomMap:(MWMZoomMode)mode {
|
||||
switch (mode) {
|
||||
case MWMZoomModeIn:
|
||||
GetFramework().Scale(Framework::SCALE_MAG, true);
|
||||
break;
|
||||
case MWMZoomModeOut:
|
||||
GetFramework().Scale(Framework::SCALE_MIN, true);
|
||||
break;
|
||||
+ (void)zoomMap:(MWMZoomMode)mode
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case MWMZoomModeIn: GetFramework().Scale(Framework::SCALE_MAG, true); break;
|
||||
case MWMZoomModeOut: GetFramework().Scale(Framework::SCALE_MIN, true); break;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)moveMap:(UIOffset)offset {
|
||||
+ (void)moveMap:(UIOffset)offset
|
||||
{
|
||||
GetFramework().Move(offset.horizontal, offset.vertical, true);
|
||||
}
|
||||
|
||||
+ (void)scrollMap:(double) distanceX :(double) distanceY {
|
||||
+ (void)scrollMap:(double)distanceX:(double)distanceY
|
||||
{
|
||||
GetFramework().Scroll(distanceX, distanceY);
|
||||
}
|
||||
|
||||
+ (void)deactivateMapSelection {
|
||||
+ (void)deactivateMapSelection
|
||||
{
|
||||
GetFramework().DeactivateMapSelection();
|
||||
}
|
||||
|
||||
+ (void)switchMyPositionMode {
|
||||
+ (void)switchMyPositionMode
|
||||
{
|
||||
GetFramework().SwitchMyPositionNextMode();
|
||||
}
|
||||
|
||||
+ (void)stopLocationFollow {
|
||||
+ (void)stopLocationFollow
|
||||
{
|
||||
GetFramework().StopLocationFollow();
|
||||
}
|
||||
|
||||
+ (void)rotateMap:(double)azimuth animated:(BOOL)isAnimated {
|
||||
+ (void)rotateMap:(double)azimuth animated:(BOOL)isAnimated
|
||||
{
|
||||
GetFramework().Rotate(azimuth, isAnimated);
|
||||
}
|
||||
|
||||
+ (void)updatePositionArrowOffset:(BOOL)useDefault offset:(int)offsetY {
|
||||
+ (void)updatePositionArrowOffset:(BOOL)useDefault offset:(int)offsetY
|
||||
{
|
||||
GetFramework().UpdateMyPositionRoutingOffset(useDefault, offsetY);
|
||||
}
|
||||
|
||||
+ (int64_t)dataVersion {
|
||||
+ (int64_t)dataVersion
|
||||
{
|
||||
return GetFramework().GetCurrentDataVersion();
|
||||
}
|
||||
|
||||
+ (void)searchInDownloader:(NSString *)query
|
||||
inputLocale:(NSString *)locale
|
||||
completion:(SearchInDownloaderCompletions)completion {
|
||||
storage::DownloaderSearchParams params{
|
||||
query.UTF8String,
|
||||
locale.precomposedStringWithCompatibilityMapping.UTF8String,
|
||||
completion:(SearchInDownloaderCompletions)completion
|
||||
{
|
||||
storage::DownloaderSearchParams params{query.UTF8String, locale.precomposedStringWithCompatibilityMapping.UTF8String,
|
||||
// m_onResults
|
||||
[completion](storage::DownloaderSearchResults const & results)
|
||||
{
|
||||
@@ -158,38 +163,44 @@
|
||||
[resultsArray addObject:result];
|
||||
}
|
||||
completion(resultsArray, results.m_endMarker);
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
GetFramework().GetSearchAPI().SearchInDownloader(std::move(params));
|
||||
}
|
||||
|
||||
+ (BOOL)canEditMapAtViewportCenter {
|
||||
+ (BOOL)canEditMapAtViewportCenter
|
||||
{
|
||||
auto const & f = GetFramework();
|
||||
return f.CanEditMapForPosition(f.GetViewportCenter());
|
||||
}
|
||||
|
||||
+ (void)showOnMap:(MWMMarkGroupID)categoryId {
|
||||
+ (void)showOnMap:(MWMMarkGroupID)categoryId
|
||||
{
|
||||
GetFramework().ShowBookmarkCategory(categoryId);
|
||||
}
|
||||
|
||||
+ (void)showBookmark:(MWMMarkID)bookmarkId {
|
||||
+ (void)showBookmark:(MWMMarkID)bookmarkId
|
||||
{
|
||||
GetFramework().ShowBookmark(bookmarkId);
|
||||
}
|
||||
|
||||
+ (void)showTrack:(MWMTrackID)trackId {
|
||||
+ (void)showTrack:(MWMTrackID)trackId
|
||||
{
|
||||
GetFramework().ShowTrack(trackId);
|
||||
}
|
||||
|
||||
+ (void)saveRouteAsTrack {
|
||||
+ (void)saveRouteAsTrack
|
||||
{
|
||||
GetFramework().SaveRoute();
|
||||
}
|
||||
|
||||
+ (void)updatePlacePageData {
|
||||
+ (void)updatePlacePageData
|
||||
{
|
||||
GetFramework().UpdatePlacePageInfoForCurrentSelection();
|
||||
}
|
||||
|
||||
+ (void)updateAfterDeleteBookmark {
|
||||
+ (void)updateAfterDeleteBookmark
|
||||
{
|
||||
auto & frm = GetFramework();
|
||||
auto buildInfo = frm.GetCurrentPlacePageInfo().GetBuildInfo();
|
||||
buildInfo.m_match = place_page::BuildInfo::Match::FeatureOnly;
|
||||
@@ -198,45 +209,54 @@
|
||||
frm.UpdatePlacePageInfoForCurrentSelection(buildInfo);
|
||||
}
|
||||
|
||||
+ (int)currentZoomLevel {
|
||||
+ (int)currentZoomLevel
|
||||
{
|
||||
return GetFramework().GetDrawScale();
|
||||
}
|
||||
|
||||
// MARK: - TrackRecorder
|
||||
|
||||
+ (void)startTrackRecording {
|
||||
+ (void)startTrackRecording
|
||||
{
|
||||
GetFramework().StartTrackRecording();
|
||||
}
|
||||
|
||||
+ (void)setTrackRecordingUpdateHandler:(TrackRecordingUpdatedHandler _Nullable)trackRecordingDidUpdate {
|
||||
+ (void)setTrackRecordingUpdateHandler:(TrackRecordingUpdatedHandler _Nullable)trackRecordingDidUpdate
|
||||
{
|
||||
if (!trackRecordingDidUpdate)
|
||||
{
|
||||
GetFramework().SetTrackRecordingUpdateHandler(nullptr);
|
||||
return;
|
||||
}
|
||||
GetFramework().SetTrackRecordingUpdateHandler([trackRecordingDidUpdate](TrackStatistics const & statistics) {
|
||||
GetFramework().SetTrackRecordingUpdateHandler([trackRecordingDidUpdate](TrackStatistics const & statistics)
|
||||
{
|
||||
TrackInfo * info = [[TrackInfo alloc] initWithTrackStatistics:statistics];
|
||||
trackRecordingDidUpdate(info);
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)stopTrackRecording {
|
||||
+ (void)stopTrackRecording
|
||||
{
|
||||
GetFramework().StopTrackRecording();
|
||||
}
|
||||
|
||||
+ (void)saveTrackRecordingWithName:(nonnull NSString *)name {
|
||||
+ (void)saveTrackRecordingWithName:(nonnull NSString *)name
|
||||
{
|
||||
GetFramework().SaveTrackRecordingWithName(name.UTF8String);
|
||||
}
|
||||
|
||||
+ (BOOL)isTrackRecordingEnabled {
|
||||
+ (BOOL)isTrackRecordingEnabled
|
||||
{
|
||||
return GetFramework().IsTrackRecordingEnabled();
|
||||
}
|
||||
|
||||
+ (BOOL)isTrackRecordingEmpty {
|
||||
+ (BOOL)isTrackRecordingEmpty
|
||||
{
|
||||
return GetFramework().IsTrackRecordingEmpty();
|
||||
}
|
||||
|
||||
+ (ElevationProfileData * _Nonnull)trackRecordingElevationInfo {
|
||||
+ (ElevationProfileData * _Nonnull)trackRecordingElevationInfo
|
||||
{
|
||||
return [[ElevationProfileData alloc] initWithElevationInfo:GetFramework().GetTrackRecordingElevationInfo()];
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
@property(nullable, nonatomic) NSFileHandle * fileHandle;
|
||||
@property(nonnull, nonatomic) os_log_t osLogger;
|
||||
/// This property is introduced to avoid the CoreApi => Maps target dependency and stores the MWMSettings.isFileLoggingEnabled value.
|
||||
/// This property is introduced to avoid the CoreApi => Maps target dependency and stores the
|
||||
/// MWMSettings.isFileLoggingEnabled value.
|
||||
@property(class, nonatomic) BOOL fileLoggingEnabled;
|
||||
@property(class, readonly, nonatomic) dispatch_queue_t fileLoggingQueue;
|
||||
|
||||
@@ -28,8 +29,8 @@ NSString * const kLoggerSubsystem = [[NSBundle mainBundle] bundleIdentifier];
|
||||
NSString * const kLoggerCategory = @"OM";
|
||||
NSString * const kLogFileName = @"log.txt";
|
||||
NSString * const kZipLogFileExtension = @"zip";
|
||||
NSString * const kLogFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
|
||||
stringByAppendingPathComponent:kLogFileName];
|
||||
NSString * const kLogFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
|
||||
firstObject] stringByAppendingPathComponent:kLogFileName];
|
||||
// TODO: (KK) Review and change this limit after some testing.
|
||||
NSUInteger const kMaxLogFileSize = 1024 * 1024 * 100; // 100 MB;
|
||||
|
||||
@@ -39,84 +40,102 @@ static BOOL _fileLoggingEnabled = NO;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [Logger class]) {
|
||||
if (self == [Logger class])
|
||||
{
|
||||
SetLogMessageFn(&LogMessage);
|
||||
SetAssertFunction(&AssertMessage);
|
||||
}
|
||||
}
|
||||
|
||||
+ (Logger *)logger {
|
||||
+ (Logger *)logger
|
||||
{
|
||||
static Logger * logger = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
logger = [[self alloc] init];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ logger = [[self alloc] init]; });
|
||||
return logger;
|
||||
}
|
||||
|
||||
+ (dispatch_queue_t)fileLoggingQueue {
|
||||
+ (dispatch_queue_t)fileLoggingQueue
|
||||
{
|
||||
static dispatch_queue_t fileLoggingQueue = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
|
||||
dispatch_queue_attr_t attributes =
|
||||
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
|
||||
fileLoggingQueue = dispatch_queue_create("app.comaps.fileLoggingQueue", attributes);
|
||||
});
|
||||
return fileLoggingQueue;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
_osLogger = os_log_create(kLoggerSubsystem.UTF8String, kLoggerCategory.UTF8String);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
+ (void)setFileLoggingEnabled:(BOOL)fileLoggingEnabled {
|
||||
+ (void)setFileLoggingEnabled:(BOOL)fileLoggingEnabled
|
||||
{
|
||||
fileLoggingEnabled ? [self enableFileLogging] : [self disableFileLogging];
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
LOG_SHORT(LINFO, ("Local time:", NSDate.date.description.UTF8String, ", Time Zone:", NSTimeZone.defaultTimeZone.abbreviation.UTF8String));
|
||||
LOG_SHORT(LINFO, ("Local time:", NSDate.date.description.UTF8String,
|
||||
", Time Zone:", NSTimeZone.defaultTimeZone.abbreviation.UTF8String));
|
||||
});
|
||||
LOG(LINFO, ("File logging is enabled:", _fileLoggingEnabled ? "YES" : "NO"));
|
||||
}
|
||||
|
||||
+ (BOOL)fileLoggingEnabled {
|
||||
+ (BOOL)fileLoggingEnabled
|
||||
{
|
||||
return _fileLoggingEnabled;
|
||||
}
|
||||
|
||||
+ (void)log:(LogLevel)level message:(NSString *)message {
|
||||
+ (void)log:(LogLevel)level message:(NSString *)message
|
||||
{
|
||||
LOG_SHORT([self baseLevel:level], (message.UTF8String));
|
||||
}
|
||||
|
||||
+ (BOOL)canLog:(LogLevel)level {
|
||||
+ (BOOL)canLog:(LogLevel)level
|
||||
{
|
||||
return [Logger baseLevel:level] >= base::g_LogLevel;
|
||||
}
|
||||
|
||||
+ (nullable NSURL *)getLogFileURL {
|
||||
if ([self fileLoggingEnabled]) {
|
||||
if (![NSFileManager.defaultManager fileExistsAtPath:kLogFilePath]) {
|
||||
+ (nullable NSURL *)getLogFileURL
|
||||
{
|
||||
if ([self fileLoggingEnabled])
|
||||
{
|
||||
if (![NSFileManager.defaultManager fileExistsAtPath:kLogFilePath])
|
||||
{
|
||||
LOG(LERROR, ("Log file doesn't exist while file logging is enabled:", kLogFilePath.UTF8String));
|
||||
return nil;
|
||||
}
|
||||
return [self getZippedLogFile:kLogFilePath];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fetch logs from the OSLog store.
|
||||
if (@available(iOS 15.0, *)) {
|
||||
if (@available(iOS 15.0, *))
|
||||
{
|
||||
NSError * error;
|
||||
OSLogStore * store = [OSLogStore storeWithScope:OSLogStoreCurrentProcessIdentifier error:&error];
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
LOG(LERROR, (error.localizedDescription.UTF8String));
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"subsystem == %@", kLoggerSubsystem];
|
||||
OSLogEnumerator * enumerator = [store entriesEnumeratorWithOptions:{} position:nil predicate:predicate error:&error];
|
||||
OSLogEnumerator * enumerator = [store entriesEnumeratorWithOptions:{}
|
||||
position:nil
|
||||
predicate:predicate
|
||||
error:&error];
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
LOG(LERROR, (error.localizedDescription.UTF8String));
|
||||
return nil;
|
||||
}
|
||||
@@ -125,27 +144,35 @@ static BOOL _fileLoggingEnabled = NO;
|
||||
NSString * kNewLineStr = @"\n";
|
||||
|
||||
id object;
|
||||
while (object = [enumerator nextObject]) {
|
||||
if ([object isMemberOfClass:[OSLogEntryLog class]]) {
|
||||
while (object = [enumerator nextObject])
|
||||
{
|
||||
if ([object isMemberOfClass:[OSLogEntryLog class]])
|
||||
{
|
||||
[logString appendString:[object composedMessage]];
|
||||
[logString appendString:kNewLineStr];
|
||||
}
|
||||
}
|
||||
|
||||
if (logString.length == 0) {
|
||||
if (logString.length == 0)
|
||||
{
|
||||
LOG(LINFO, ("OSLog entry is empty."));
|
||||
return nil;
|
||||
}
|
||||
|
||||
[NSFileManager.defaultManager createFileAtPath:kLogFilePath contents:[logString dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
|
||||
[NSFileManager.defaultManager createFileAtPath:kLogFilePath
|
||||
contents:[logString dataUsingEncoding:NSUTF8StringEncoding]
|
||||
attributes:nil];
|
||||
return [self getZippedLogFile:kLogFilePath];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (uint64_t)getLogFileSize {
|
||||
+ (uint64_t)getLogFileSize
|
||||
{
|
||||
Logger * logger = [self logger];
|
||||
return logger.fileHandle != nil ? [logger.fileHandle offsetInFile] : 0;
|
||||
}
|
||||
@@ -166,7 +193,8 @@ bool AssertMessage(base::SrcPoint const & src, std::string const & message)
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
+ (void)enableFileLogging {
|
||||
+ (void)enableFileLogging
|
||||
{
|
||||
Logger * logger = [self logger];
|
||||
NSFileManager * fileManager = [NSFileManager defaultManager];
|
||||
|
||||
@@ -174,7 +202,8 @@ bool AssertMessage(base::SrcPoint const & src, std::string const & message)
|
||||
if (![fileManager fileExistsAtPath:kLogFilePath])
|
||||
[fileManager createFileAtPath:kLogFilePath contents:nil attributes:nil];
|
||||
NSFileHandle * fileHandle = [NSFileHandle fileHandleForWritingAtPath:kLogFilePath];
|
||||
if (fileHandle == nil) {
|
||||
if (fileHandle == nil)
|
||||
{
|
||||
LOG(LERROR, ("Failed to open log file for writing", kLogFilePath.UTF8String));
|
||||
[self disableFileLogging];
|
||||
return;
|
||||
@@ -188,7 +217,8 @@ bool AssertMessage(base::SrcPoint const & src, std::string const & message)
|
||||
_fileLoggingEnabled = YES;
|
||||
}
|
||||
|
||||
+ (void)disableFileLogging {
|
||||
+ (void)disableFileLogging
|
||||
{
|
||||
Logger * logger = [self logger];
|
||||
|
||||
[logger.fileHandle closeFile];
|
||||
@@ -198,7 +228,8 @@ bool AssertMessage(base::SrcPoint const & src, std::string const & message)
|
||||
_fileLoggingEnabled = NO;
|
||||
}
|
||||
|
||||
+ (void)logMessageWithLevel:(base::LogLevel)level src:(base::SrcPoint const &)src message:(std::string const &)message {
|
||||
+ (void)logMessageWithLevel:(base::LogLevel)level src:(base::SrcPoint const &)src message:(std::string const &)message
|
||||
{
|
||||
// Build the log message string.
|
||||
auto & logHelper = base::LogHelper::Instance();
|
||||
std::ostringstream output;
|
||||
@@ -217,27 +248,35 @@ bool AssertMessage(base::SrcPoint const & src, std::string const & message)
|
||||
[self tryWriteToFile:logString];
|
||||
}
|
||||
|
||||
+ (void)tryWriteToFile:(std::string const &)logString {
|
||||
+ (void)tryWriteToFile:(std::string const &)logString
|
||||
{
|
||||
NSFileHandle * fileHandle = [self logger].fileHandle;
|
||||
if (fileHandle != nil) {
|
||||
if (fileHandle != nil)
|
||||
{
|
||||
[fileHandle seekToEndOfFile];
|
||||
[fileHandle writeData:[NSData dataWithBytes:logString.c_str() length:logString.length()]];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSURL *)getZippedLogFile:(NSString *)logFilePath {
|
||||
NSString * zipFileName = [[logFilePath.lastPathComponent stringByDeletingPathExtension] stringByAppendingPathExtension:kZipLogFileExtension];
|
||||
NSString * zipFilePath = [[NSFileManager.defaultManager temporaryDirectory] URLByAppendingPathComponent:zipFileName].path;
|
||||
+ (NSURL *)getZippedLogFile:(NSString *)logFilePath
|
||||
{
|
||||
NSString * zipFileName = [[logFilePath.lastPathComponent stringByDeletingPathExtension]
|
||||
stringByAppendingPathExtension:kZipLogFileExtension];
|
||||
NSString * zipFilePath =
|
||||
[[NSFileManager.defaultManager temporaryDirectory] URLByAppendingPathComponent:zipFileName].path;
|
||||
auto const success = CreateZipFromFiles({logFilePath.UTF8String}, zipFilePath.UTF8String);
|
||||
if (!success) {
|
||||
if (!success)
|
||||
{
|
||||
LOG(LERROR, ("Failed to zip log file:", kLogFilePath.UTF8String, ". The original file will be returned."));
|
||||
return [NSURL fileURLWithPath:logFilePath];
|
||||
}
|
||||
return [NSURL fileURLWithPath:zipFilePath];
|
||||
}
|
||||
|
||||
+ (void)removeFileAtPath:(NSString *)filePath {
|
||||
if ([NSFileManager.defaultManager fileExistsAtPath:filePath]) {
|
||||
+ (void)removeFileAtPath:(NSString *)filePath
|
||||
{
|
||||
if ([NSFileManager.defaultManager fileExistsAtPath:filePath])
|
||||
{
|
||||
NSError * error;
|
||||
[NSFileManager.defaultManager removeItemAtPath:filePath error:&error];
|
||||
if (error)
|
||||
@@ -245,8 +284,10 @@ bool AssertMessage(base::SrcPoint const & src, std::string const & message)
|
||||
}
|
||||
}
|
||||
|
||||
+ (base::LogLevel)baseLevel:(LogLevel)level {
|
||||
switch (level) {
|
||||
+ (base::LogLevel)baseLevel:(LogLevel)level
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case LogLevelDebug: return LDEBUG;
|
||||
case LogLevelInfo: return LINFO;
|
||||
case LogLevelWarning: return LWARNING;
|
||||
|
||||
@@ -5,68 +5,57 @@
|
||||
|
||||
@implementation MWMNetworkPolicy
|
||||
|
||||
+ (MWMNetworkPolicy *)sharedPolicy {
|
||||
+ (MWMNetworkPolicy *)sharedPolicy
|
||||
{
|
||||
static MWMNetworkPolicy * policy;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
policy = [[MWMNetworkPolicy alloc] init];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ policy = [[MWMNetworkPolicy alloc] init]; });
|
||||
return policy;
|
||||
}
|
||||
|
||||
- (MWMNetworkPolicyPermission)permission {
|
||||
switch (network_policy::GetStage()) {
|
||||
case network_policy::Ask:
|
||||
return MWMNetworkPolicyPermissionAsk;
|
||||
case network_policy::Always:
|
||||
return MWMNetworkPolicyPermissionAlways;
|
||||
case network_policy::Never:
|
||||
return MWMNetworkPolicyPermissionNever;
|
||||
case network_policy::Today:
|
||||
return MWMNetworkPolicyPermissionToday;
|
||||
case network_policy::NotToday:
|
||||
return MWMNetworkPolicyPermissionNotToday;
|
||||
- (MWMNetworkPolicyPermission)permission
|
||||
{
|
||||
switch (network_policy::GetStage())
|
||||
{
|
||||
case network_policy::Ask: return MWMNetworkPolicyPermissionAsk;
|
||||
case network_policy::Always: return MWMNetworkPolicyPermissionAlways;
|
||||
case network_policy::Never: return MWMNetworkPolicyPermissionNever;
|
||||
case network_policy::Today: return MWMNetworkPolicyPermissionToday;
|
||||
case network_policy::NotToday: return MWMNetworkPolicyPermissionNotToday;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setPermission:(MWMNetworkPolicyPermission)permission {
|
||||
- (void)setPermission:(MWMNetworkPolicyPermission)permission
|
||||
{
|
||||
network_policy::Stage stage;
|
||||
switch (permission) {
|
||||
case MWMNetworkPolicyPermissionAsk:
|
||||
stage = network_policy::Stage::Ask;
|
||||
break;
|
||||
case MWMNetworkPolicyPermissionAlways:
|
||||
stage = network_policy::Stage::Always;
|
||||
break;
|
||||
case MWMNetworkPolicyPermissionNever:
|
||||
stage = network_policy::Stage::Never;
|
||||
break;
|
||||
case MWMNetworkPolicyPermissionToday:
|
||||
stage = network_policy::Stage::Today;
|
||||
break;
|
||||
case MWMNetworkPolicyPermissionNotToday:
|
||||
stage = network_policy::Stage::NotToday;
|
||||
break;
|
||||
switch (permission)
|
||||
{
|
||||
case MWMNetworkPolicyPermissionAsk: stage = network_policy::Stage::Ask; break;
|
||||
case MWMNetworkPolicyPermissionAlways: stage = network_policy::Stage::Always; break;
|
||||
case MWMNetworkPolicyPermissionNever: stage = network_policy::Stage::Never; break;
|
||||
case MWMNetworkPolicyPermissionToday: stage = network_policy::Stage::Today; break;
|
||||
case MWMNetworkPolicyPermissionNotToday: stage = network_policy::Stage::NotToday; break;
|
||||
}
|
||||
network_policy::SetStage(stage);
|
||||
}
|
||||
|
||||
- (NSDate *)permissionExpirationDate {
|
||||
- (NSDate *)permissionExpirationDate
|
||||
{
|
||||
return network_policy::GetPolicyDate();
|
||||
}
|
||||
|
||||
- (BOOL)canUseNetwork {
|
||||
- (BOOL)canUseNetwork
|
||||
{
|
||||
return network_policy::CanUseNetwork();
|
||||
}
|
||||
|
||||
- (MWMConnectionType)connectionType {
|
||||
switch (GetPlatform().ConnectionStatus()) {
|
||||
case Platform::EConnectionType::CONNECTION_NONE:
|
||||
return MWMConnectionTypeNone;
|
||||
case Platform::EConnectionType::CONNECTION_WIFI:
|
||||
return MWMConnectionTypeWifi;
|
||||
case Platform::EConnectionType::CONNECTION_WWAN:
|
||||
return MWMConnectionTypeCellular;
|
||||
- (MWMConnectionType)connectionType
|
||||
{
|
||||
switch (GetPlatform().ConnectionStatus())
|
||||
{
|
||||
case Platform::EConnectionType::CONNECTION_NONE: return MWMConnectionTypeNone;
|
||||
case Platform::EConnectionType::CONNECTION_WIFI: return MWMConnectionTypeWifi;
|
||||
case Platform::EConnectionType::CONNECTION_WWAN: return MWMConnectionTypeCellular;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,7 @@ namespace
|
||||
{
|
||||
NSString * stringFromTimeSpan(Timespan const & timeSpan)
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ - %@", stringFromTime(timeSpan.GetStart()),
|
||||
stringFromTime(timeSpan.GetEnd())];
|
||||
return [NSString stringWithFormat:@"%@ - %@", stringFromTime(timeSpan.GetStart()), stringFromTime(timeSpan.GetEnd())];
|
||||
}
|
||||
|
||||
NSString * breaksFromClosedTime(TTimespans const & closedTimes, id<IOpeningHoursLocalization> localization)
|
||||
@@ -22,8 +21,8 @@ NSString * breaksFromClosedTime(TTimespans const & closedTimes, id<IOpeningHours
|
||||
{
|
||||
if (i)
|
||||
[breaks appendString:@"\n"];
|
||||
[breaks appendString:[NSString stringWithFormat:@"%@ %@", localization.breakString,
|
||||
stringFromTimeSpan(closedTimes[i])]];
|
||||
[breaks appendString:[NSString
|
||||
stringWithFormat:@"%@ %@", localization.breakString, stringFromTimeSpan(closedTimes[i])]];
|
||||
}
|
||||
return [breaks copy];
|
||||
}
|
||||
@@ -81,7 +80,8 @@ void addUnhandledDays(ui::OpeningDays const & days, std::vector<Day> & allDays)
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace osmoh {
|
||||
namespace osmoh
|
||||
{
|
||||
|
||||
std::pair<std::vector<osmoh::Day>, bool> processRawString(NSString * str, id<IOpeningHoursLocalization> localization)
|
||||
{
|
||||
@@ -98,8 +98,7 @@ std::pair<std::vector<osmoh::Day>, bool> processRawString(NSString *str, id<IOpe
|
||||
cal.locale = NSLocale.currentLocale;
|
||||
|
||||
auto const timeTablesSize = timeTableSet.Size();
|
||||
auto const today =
|
||||
static_cast<Weekday>([cal components:NSCalendarUnitWeekday fromDate:[NSDate date]].weekday);
|
||||
auto const today = static_cast<Weekday>([cal components:NSCalendarUnitWeekday fromDate:[NSDate date]].weekday);
|
||||
auto const unhandledDays = timeTableSet.GetUnhandledDays();
|
||||
|
||||
/// Schedule contains more than one rule for all days or unhandled days.
|
||||
|
||||
@@ -33,16 +33,14 @@ NSString * stringFromOpeningDays(editor::ui::OpeningDays const & openingDays)
|
||||
NSMutableArray<NSString *> * spanNames = [NSMutableArray arrayWithCapacity:2];
|
||||
NSMutableArray<NSString *> * spans = [NSMutableArray array];
|
||||
|
||||
auto weekdayFromDay = ^(NSUInteger day)
|
||||
{
|
||||
auto weekdayFromDay = ^(NSUInteger day) {
|
||||
NSUInteger idx = day + 1;
|
||||
if (idx > static_cast<NSUInteger>(osmoh::Weekday::Saturday))
|
||||
idx -= static_cast<NSUInteger>(osmoh::Weekday::Saturday);
|
||||
return static_cast<osmoh::Weekday>(idx);
|
||||
};
|
||||
|
||||
auto joinSpanNames = ^
|
||||
{
|
||||
auto joinSpanNames = ^{
|
||||
NSUInteger const spanNamesCount = spanNames.count;
|
||||
if (spanNamesCount == 0)
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "OpeningHours.h"
|
||||
|
||||
#import "MWMOpeningHours.h"
|
||||
#include "3party/opening_hours/opening_hours.hpp"
|
||||
#import "MWMOpeningHours.h"
|
||||
|
||||
@interface WorkingDay ()
|
||||
|
||||
@@ -25,13 +25,16 @@
|
||||
|
||||
@implementation OpeningHours
|
||||
|
||||
- (instancetype)initWithRawString:(NSString *)rawString localization:(id<IOpeningHoursLocalization>)localization {
|
||||
- (instancetype)initWithRawString:(NSString *)rawString localization:(id<IOpeningHoursLocalization>)localization
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
auto const [days, isClosed] = osmoh::processRawString(rawString, localization);
|
||||
_isClosedNow = isClosed;
|
||||
NSMutableArray * array = [NSMutableArray arrayWithCapacity:days.size()];
|
||||
for (auto const & day : days) {
|
||||
for (auto const & day : days)
|
||||
{
|
||||
WorkingDay * wd = [[WorkingDay alloc] init];
|
||||
wd.isOpen = day.m_isOpen;
|
||||
wd.workingDays = day.m_workingDays;
|
||||
@@ -39,9 +42,8 @@
|
||||
wd.breaks = day.m_breaks;
|
||||
[array addObject:wd];
|
||||
}
|
||||
if (array.count == 0) {
|
||||
if (array.count == 0)
|
||||
return nil;
|
||||
}
|
||||
_days = [array copy];
|
||||
}
|
||||
return self;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "PlacePageBookmarkData+Core.h"
|
||||
#import "MWMBookmarkColor+Core.h"
|
||||
#import "PlacePageBookmarkData+Core.h"
|
||||
|
||||
@implementation PlacePageBookmarkData
|
||||
|
||||
@@ -7,13 +7,16 @@
|
||||
|
||||
@implementation PlacePageBookmarkData (Core)
|
||||
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData {
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_bookmarkId = rawData.GetBookmarkId();
|
||||
_bookmarkGroupId = rawData.GetBookmarkCategoryId();
|
||||
_externalTitle = rawData.GetSecondaryTitle().empty() ? nil : @(rawData.GetSecondaryTitle().c_str());
|
||||
_bookmarkDescription = rawData.IsBookmark() ? @(GetPreferredBookmarkStr(rawData.GetBookmarkData().m_description).c_str()) : nil;
|
||||
_bookmarkDescription =
|
||||
rawData.IsBookmark() ? @(GetPreferredBookmarkStr(rawData.GetBookmarkData().m_description).c_str()) : nil;
|
||||
_bookmarkCategory = rawData.IsBookmark() ? @(rawData.GetBookmarkCategoryName().c_str()) : nil;
|
||||
_isHtmlDescription = strings::IsHTML(GetPreferredBookmarkStr(rawData.GetBookmarkData().m_description));
|
||||
_color = convertKmlColor(rawData.GetBookmarkData().m_color.m_predefinedColor);
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
@implementation PlacePageButtonsData (Core)
|
||||
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData {
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_showAddPlace = rawData.ShouldShowAddPlace() || rawData.ShouldShowAddBusiness();
|
||||
_showEditPlace = rawData.ShouldShowEditPlace();
|
||||
_enableAddPlace = rawData.ShouldEnableAddPlace();
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include "platform/localization.hpp"
|
||||
|
||||
#include "indexer/validate_and_format_contacts.hpp"
|
||||
#include "indexer/feature_meta.hpp"
|
||||
#include "indexer/validate_and_format_contacts.hpp"
|
||||
|
||||
#include "map/place_page_info.hpp"
|
||||
|
||||
@@ -16,7 +16,8 @@ using namespace place_page;
|
||||
using namespace osm;
|
||||
|
||||
/// Get localized metadata value string when string format is "type.feature.value".
|
||||
NSString * GetLocalizedMetadataValueString(MapObject::MetadataID metaID, std::string const & value) {
|
||||
NSString * GetLocalizedMetadataValueString(MapObject::MetadataID metaID, std::string const & value)
|
||||
{
|
||||
return ToNSString(platform::GetLocalizedTypeName(feature::ToString(metaID) + "." + value));
|
||||
}
|
||||
|
||||
@@ -26,7 +27,8 @@ NSString * GetLocalizedMetadataValueString(MapObject::MetadataID metaID, std::st
|
||||
|
||||
@implementation PlacePageInfoData (Core)
|
||||
|
||||
- (instancetype)initWithRawData:(Info const &)rawData ohLocalization:(id<IOpeningHoursLocalization>)localization {
|
||||
- (instancetype)initWithRawData:(Info const &)rawData ohLocalization:(id<IOpeningHoursLocalization>)localization
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
@@ -42,18 +44,18 @@ NSString * GetLocalizedMetadataValueString(MapObject::MetadataID metaID, std::st
|
||||
{
|
||||
case MetadataID::FMD_OPEN_HOURS:
|
||||
_openingHoursString = ToNSString(value);
|
||||
_openingHours = [[OpeningHours alloc] initWithRawString:_openingHoursString
|
||||
localization:localization];
|
||||
_openingHours = [[OpeningHours alloc] initWithRawString:_openingHoursString localization:localization];
|
||||
break;
|
||||
case MetadataID::FMD_PHONE_NUMBER:
|
||||
{
|
||||
NSArray<NSString *> * phones = [ToNSString(value) componentsSeparatedByString:@";"];
|
||||
NSMutableArray<PlacePagePhone *> * placePhones = [NSMutableArray new];
|
||||
[phones enumerateObjectsUsingBlock:^(NSString * _Nonnull phone, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
NSString *filteredDigits = [[phone componentsSeparatedByCharactersInSet:
|
||||
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
|
||||
NSString * filteredDigits =
|
||||
[[phone componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
|
||||
componentsJoinedByString:@""];
|
||||
NSString *resultNumber = [phone hasPrefix:@"+"] ? [NSString stringWithFormat:@"+%@", filteredDigits] : filteredDigits;
|
||||
NSString * resultNumber =
|
||||
[phone hasPrefix:@"+"] ? [NSString stringWithFormat:@"+%@", filteredDigits] : filteredDigits;
|
||||
NSURL * phoneUrl = [NSURL URLWithString:[NSString stringWithFormat:@"tel://%@", resultNumber]];
|
||||
|
||||
[placePhones addObject:[PlacePagePhone placePagePhoneWithPhone:phone andURL:phoneUrl]];
|
||||
@@ -76,13 +78,17 @@ NSString * GetLocalizedMetadataValueString(MapObject::MetadataID metaID, std::st
|
||||
case MetadataID::FMD_CONTACT_LINE: _line = ToNSString(value); break;
|
||||
case MetadataID::FMD_CONTACT_BLUESKY: _bluesky = ToNSString(value); break;
|
||||
case MetadataID::FMD_PANORAMAX: _panoramax = ToNSString(value); break;
|
||||
case MetadataID::FMD_OPERATOR: _ppOperator = [NSString stringWithFormat:NSLocalizedString(@"operator", nil), ToNSString(value)]; break;
|
||||
case MetadataID::FMD_OPERATOR:
|
||||
_ppOperator = [NSString stringWithFormat:NSLocalizedString(@"operator", nil), ToNSString(value)];
|
||||
break;
|
||||
case MetadataID::FMD_INTERNET:
|
||||
_wifiAvailable = (rawData.GetInternet() == feature::Internet::No)
|
||||
? NSLocalizedString(@"no_available", nil) : NSLocalizedString(@"yes_available", nil);
|
||||
_wifiAvailable = (rawData.GetInternet() == feature::Internet::No) ? NSLocalizedString(@"no_available", nil)
|
||||
: NSLocalizedString(@"yes_available", nil);
|
||||
break;
|
||||
case MetadataID::FMD_LEVEL: _level = ToNSString(value); break;
|
||||
case MetadataID::FMD_CAPACITY: _capacity = [NSString stringWithFormat:NSLocalizedString(@"capacity", nil), ToNSString(value)]; break;
|
||||
case MetadataID::FMD_CAPACITY:
|
||||
_capacity = [NSString stringWithFormat:NSLocalizedString(@"capacity", nil), ToNSString(value)];
|
||||
break;
|
||||
case MetadataID::FMD_WHEELCHAIR: _wheelchair = ToNSString(platform::GetLocalizedTypeName(value)); break;
|
||||
case MetadataID::FMD_DRIVE_THROUGH:
|
||||
if (value == "yes")
|
||||
@@ -94,21 +100,24 @@ NSString * GetLocalizedMetadataValueString(MapObject::MetadataID metaID, std::st
|
||||
if (value == "yes")
|
||||
_outdoorSeating = NSLocalizedString(@"outdoor_seating", nil);
|
||||
break;
|
||||
case MetadataID::FMD_NETWORK: _network = [NSString stringWithFormat:NSLocalizedString(@"network", nil), ToNSString(value)]; break;
|
||||
default:
|
||||
case MetadataID::FMD_NETWORK:
|
||||
_network = [NSString stringWithFormat:NSLocalizedString(@"network", nil), ToNSString(value)];
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
});
|
||||
|
||||
_atm = rawData.HasAtm() ? NSLocalizedString(@"type.amenity.atm", nil) : nil;
|
||||
|
||||
_address = rawData.GetSecondarySubtitle().empty() ? nil : @(rawData.GetSecondarySubtitle().c_str());
|
||||
_coordFormats = @[@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::LatLonDMS).c_str()),
|
||||
_coordFormats = @[
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::LatLonDMS).c_str()),
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::LatLonDecimal).c_str()),
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::OLCFull).c_str()),
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::OSMLink).c_str()),
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::UTM).c_str()),
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::MGRS).c_str())];
|
||||
@(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::MGRS).c_str())
|
||||
];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "PlacePagePreviewData+Core.h"
|
||||
#import "DistanceFormatter.h"
|
||||
#import "AltitudeFormatter.h"
|
||||
#import "DistanceFormatter.h"
|
||||
#import "DurationFormatter.h"
|
||||
#import "PlacePagePreviewData+Core.h"
|
||||
#import "TrackInfo.h"
|
||||
|
||||
#include "3party/opening_hours/opening_hours.hpp"
|
||||
@@ -10,26 +10,30 @@ static PlacePageDataSchedule convertOpeningHours(std::string_view rawOH)
|
||||
{
|
||||
PlacePageDataSchedule schedule;
|
||||
|
||||
if (rawOH.empty()) {
|
||||
if (rawOH.empty())
|
||||
{
|
||||
schedule.state = PlacePageDataOpeningHoursUnknown;
|
||||
return schedule;
|
||||
}
|
||||
|
||||
/// @todo Avoid temporary string when OpeningHours (boost::spirit) will allow string_view.
|
||||
osmoh::OpeningHours oh((std::string(rawOH)));
|
||||
if (!oh.IsValid()) {
|
||||
if (!oh.IsValid())
|
||||
{
|
||||
schedule.state = PlacePageDataOpeningHoursUnknown;
|
||||
return schedule;
|
||||
}
|
||||
|
||||
if (oh.IsTwentyFourHours()) {
|
||||
if (oh.IsTwentyFourHours())
|
||||
{
|
||||
schedule.state = PlacePageDataOpeningHoursAllDay;
|
||||
return schedule;
|
||||
}
|
||||
|
||||
auto const t = time(nullptr);
|
||||
osmoh::OpeningHours::InfoT info = oh.GetInfo(t);
|
||||
switch (info.state) {
|
||||
switch (info.state)
|
||||
{
|
||||
case osmoh::RuleState::Open:
|
||||
schedule.state = PlacePageDataOpeningHoursOpen;
|
||||
schedule.nextTimeClosed = info.nextTimeClosed;
|
||||
@@ -40,9 +44,7 @@ static PlacePageDataSchedule convertOpeningHours(std::string_view rawOH)
|
||||
schedule.nextTimeOpen = info.nextTimeOpen;
|
||||
break;
|
||||
|
||||
case osmoh::RuleState::Unknown:
|
||||
schedule.state = PlacePageDataOpeningHoursUnknown;
|
||||
break;
|
||||
case osmoh::RuleState::Unknown: schedule.state = PlacePageDataOpeningHoursUnknown; break;
|
||||
}
|
||||
|
||||
return schedule;
|
||||
@@ -50,9 +52,11 @@ static PlacePageDataSchedule convertOpeningHours(std::string_view rawOH)
|
||||
|
||||
@implementation PlacePagePreviewData
|
||||
|
||||
- (instancetype)initWithTrackInfo:(TrackInfo * _Nonnull)trackInfo {
|
||||
- (instancetype)initWithTrackInfo:(TrackInfo * _Nonnull)trackInfo
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
NSString * kSeparator = @" • ";
|
||||
_title = [@[trackInfo.duration, trackInfo.distance] componentsJoinedByString:kSeparator];
|
||||
}
|
||||
@@ -63,15 +67,18 @@ static PlacePageDataSchedule convertOpeningHours(std::string_view rawOH)
|
||||
|
||||
@implementation PlacePagePreviewData (Core)
|
||||
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData {
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_title = rawData.GetTitle().empty() ? nil : @(rawData.GetTitle().c_str());
|
||||
_secondaryTitle = rawData.GetSecondaryTitle().empty() ? nil : @(rawData.GetSecondaryTitle().c_str());
|
||||
_subtitle = rawData.GetSubtitle().empty() ? nil : @(rawData.GetSubtitle().c_str());
|
||||
_secondarySubtitle = rawData.GetSecondarySubtitle().empty() ? nil : @(rawData.GetSecondarySubtitle().c_str());
|
||||
|
||||
if (!rawData.IsTrack()) {
|
||||
if (!rawData.IsTrack())
|
||||
{
|
||||
_coordinates = @(rawData.GetFormattedCoordinate(place_page::CoordinatesFormat::LatLonDMS).c_str());
|
||||
_isMyPosition = rawData.IsMyPosition();
|
||||
_schedule = convertOpeningHours(rawData.GetOpeningHours());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "PlacePageTrackData+Core.h"
|
||||
#import "ElevationProfileData+Core.h"
|
||||
#import "PlacePageTrackData+Core.h"
|
||||
#import "TrackInfo+Core.h"
|
||||
|
||||
@interface PlacePageTrackData ()
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
- (instancetype)initWithTrackInfo:(TrackInfo *)trackInfo
|
||||
elevationInfo:(ElevationProfileData * _Nullable)elevationInfo
|
||||
onActivePointChanged:(MWMVoidBlock)onActivePointChangedHandler {
|
||||
onActivePointChanged:(MWMVoidBlock)onActivePointChangedHandler
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_trackInfo = trackInfo;
|
||||
_elevationProfileData = elevationInfo;
|
||||
_onActivePointChangedHandler = onActivePointChangedHandler;
|
||||
@@ -22,7 +24,8 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateActivePointDistance:(double)distance {
|
||||
- (void)updateActivePointDistance:(double)distance
|
||||
{
|
||||
self.activePointDistance = distance;
|
||||
if (self.onActivePointChangedHandler)
|
||||
self.onActivePointChangedHandler();
|
||||
@@ -33,9 +36,11 @@
|
||||
@implementation PlacePageTrackData (Core)
|
||||
|
||||
- (instancetype)initWithRawData:(place_page::Info const &)rawData
|
||||
onActivePointChanged:(MWMVoidBlock)onActivePointChangedHandler {
|
||||
onActivePointChanged:(MWMVoidBlock)onActivePointChangedHandler
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
auto const trackPtr = GetFramework().GetBookmarkManager().GetTrack(rawData.GetTrackId());
|
||||
auto const & track = *trackPtr;
|
||||
auto const & bm = GetFramework().GetBookmarkManager();
|
||||
@@ -43,7 +48,8 @@
|
||||
_trackId = track.GetData().m_id;
|
||||
|
||||
auto const & groupId = track.GetGroupId();
|
||||
if (groupId && bm.HasBmCategory(groupId)) {
|
||||
if (groupId && bm.HasBmCategory(groupId))
|
||||
{
|
||||
_groupId = groupId;
|
||||
_trackCategory = [NSString stringWithCString:bm.GetCategoryName(groupId).c_str() encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
@@ -58,7 +64,8 @@
|
||||
_onActivePointChangedHandler = onActivePointChangedHandler;
|
||||
|
||||
auto const & elevationInfo = track.GetElevationInfo();
|
||||
if (track.HasAltitudes() && elevationInfo.has_value()) {
|
||||
if (track.HasAltitudes() && elevationInfo.has_value())
|
||||
{
|
||||
_elevationProfileData = [[ElevationProfileData alloc] initWithTrackId:_trackId
|
||||
elevationInfo:elevationInfo.value()];
|
||||
}
|
||||
|
||||
@@ -2,16 +2,14 @@
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
static ElevationDifficulty convertDifficulty(uint8_t difficulty) {
|
||||
switch (difficulty) {
|
||||
case ElevationInfo::Difficulty::Easy:
|
||||
return ElevationDifficulty::ElevationDifficultyEasy;
|
||||
case ElevationInfo::Difficulty::Medium:
|
||||
return ElevationDifficulty::ElevationDifficultyMedium;
|
||||
case ElevationInfo::Difficulty::Hard:
|
||||
return ElevationDifficulty::ElevationDifficultyHard;
|
||||
case ElevationInfo::Difficulty::Unknown:
|
||||
return ElevationDifficulty::ElevationDifficultyDisabled;
|
||||
static ElevationDifficulty convertDifficulty(uint8_t difficulty)
|
||||
{
|
||||
switch (difficulty)
|
||||
{
|
||||
case ElevationInfo::Difficulty::Easy: return ElevationDifficulty::ElevationDifficultyEasy;
|
||||
case ElevationInfo::Difficulty::Medium: return ElevationDifficulty::ElevationDifficultyMedium;
|
||||
case ElevationInfo::Difficulty::Hard: return ElevationDifficulty::ElevationDifficultyHard;
|
||||
case ElevationInfo::Difficulty::Unknown: return ElevationDifficulty::ElevationDifficultyDisabled;
|
||||
}
|
||||
return ElevationDifficulty::ElevationDifficultyDisabled;
|
||||
}
|
||||
@@ -22,10 +20,11 @@ static ElevationDifficulty convertDifficulty(uint8_t difficulty) {
|
||||
|
||||
@implementation ElevationProfileData (Core)
|
||||
|
||||
- (instancetype)initWithTrackId:(MWMTrackID)trackId
|
||||
elevationInfo:(ElevationInfo const &)elevationInfo {
|
||||
- (instancetype)initWithTrackId:(MWMTrackID)trackId elevationInfo:(ElevationInfo const &)elevationInfo
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_trackId = trackId;
|
||||
_difficulty = convertDifficulty(elevationInfo.GetDifficulty());
|
||||
_points = [ElevationProfileData pointsFromElevationInfo:elevationInfo];
|
||||
@@ -34,9 +33,11 @@ static ElevationDifficulty convertDifficulty(uint8_t difficulty) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithElevationInfo:(ElevationInfo const &)elevationInfo {
|
||||
- (instancetype)initWithElevationInfo:(ElevationInfo const &)elevationInfo
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_difficulty = convertDifficulty(elevationInfo.GetDifficulty());
|
||||
_points = [ElevationProfileData pointsFromElevationInfo:elevationInfo];
|
||||
_isTrackRecording = true;
|
||||
@@ -44,13 +45,16 @@ static ElevationDifficulty convertDifficulty(uint8_t difficulty) {
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSArray<ElevationHeightPoint *> *)pointsFromElevationInfo:(ElevationInfo const &)elevationInfo {
|
||||
+ (NSArray<ElevationHeightPoint *> *)pointsFromElevationInfo:(ElevationInfo const &)elevationInfo
|
||||
{
|
||||
auto const & points = elevationInfo.GetPoints();
|
||||
NSMutableArray * pointsArray = [[NSMutableArray alloc] initWithCapacity:points.size()];
|
||||
for (auto const & point : points) {
|
||||
for (auto const & point : points)
|
||||
{
|
||||
auto pointLatLon = mercator::ToLatLon(point.m_point.GetPoint());
|
||||
CLLocationCoordinate2D coordinates = CLLocationCoordinate2DMake(pointLatLon.m_lat, pointLatLon.m_lon);
|
||||
ElevationHeightPoint * elevationPoint = [[ElevationHeightPoint alloc] initWithCoordinates:coordinates
|
||||
ElevationHeightPoint * elevationPoint =
|
||||
[[ElevationHeightPoint alloc] initWithCoordinates:coordinates
|
||||
distance:point.m_distance
|
||||
andAltitude:point.m_point.GetAltitude()];
|
||||
[pointsArray addObject:elevationPoint];
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
#import "PlacePageData.h"
|
||||
|
||||
#import "PlacePageButtonsData+Core.h"
|
||||
#import "PlacePagePreviewData+Core.h"
|
||||
#import "PlacePageInfoData+Core.h"
|
||||
#import "PlacePageBookmarkData+Core.h"
|
||||
#import "PlacePageTrackData+Core.h"
|
||||
#import "ElevationProfileData+Core.h"
|
||||
#import "MWMMapNodeAttributes.h"
|
||||
#import "PlacePageBookmarkData+Core.h"
|
||||
#import "PlacePageButtonsData+Core.h"
|
||||
#import "PlacePageInfoData+Core.h"
|
||||
#import "PlacePagePreviewData+Core.h"
|
||||
#import "PlacePageTrackData+Core.h"
|
||||
|
||||
#include <CoreApi/CoreApi.h>
|
||||
#include "platform/network_policy.hpp"
|
||||
|
||||
static place_page::Info & rawData() { return GetFramework().GetCurrentPlacePageInfo(); }
|
||||
static place_page::Info & rawData()
|
||||
{
|
||||
return GetFramework().GetCurrentPlacePageInfo();
|
||||
}
|
||||
|
||||
static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType) {
|
||||
switch (roadType) {
|
||||
case RoadWarningMarkType::Toll:
|
||||
return PlacePageRoadTypeToll;
|
||||
case RoadWarningMarkType::Ferry:
|
||||
return PlacePageRoadTypeFerry;
|
||||
case RoadWarningMarkType::Dirty:
|
||||
return PlacePageRoadTypeDirty;
|
||||
case RoadWarningMarkType::Count:
|
||||
return PlacePageRoadTypeNone;
|
||||
static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType)
|
||||
{
|
||||
switch (roadType)
|
||||
{
|
||||
case RoadWarningMarkType::Toll: return PlacePageRoadTypeToll;
|
||||
case RoadWarningMarkType::Ferry: return PlacePageRoadTypeFerry;
|
||||
case RoadWarningMarkType::Dirty: return PlacePageRoadTypeDirty;
|
||||
case RoadWarningMarkType::Count: return PlacePageRoadTypeNone;
|
||||
}
|
||||
}
|
||||
|
||||
@interface PlacePageData () <MWMStorageObserver> {
|
||||
@interface PlacePageData () <MWMStorageObserver>
|
||||
{
|
||||
FeatureID m_featureID;
|
||||
m2::PointD m_mercator;
|
||||
std::vector<std::string> m_rawTypes;
|
||||
@@ -41,19 +43,19 @@ static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType) {
|
||||
|
||||
@implementation PlacePageData
|
||||
|
||||
- (instancetype)initWithLocalizationProvider:(id<IOpeningHoursLocalization>)localization {
|
||||
- (instancetype)initWithLocalizationProvider:(id<IOpeningHoursLocalization>)localization
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_buttonsData = [[PlacePageButtonsData alloc] initWithRawData:rawData()];
|
||||
_infoData = [[PlacePageInfoData alloc] initWithRawData:rawData() ohLocalization:localization];
|
||||
|
||||
if (rawData().IsBookmark()) {
|
||||
if (rawData().IsBookmark())
|
||||
_bookmarkData = [[PlacePageBookmarkData alloc] initWithRawData:rawData()];
|
||||
}
|
||||
|
||||
if (auto const & wikiDescription = rawData().GetWikiDescription(); !wikiDescription.empty()) {
|
||||
if (auto const & wikiDescription = rawData().GetWikiDescription(); !wikiDescription.empty())
|
||||
_wikiDescriptionHtml = @(("<html><body>" + wikiDescription + "</body></html>").c_str());
|
||||
}
|
||||
|
||||
_roadType = convertRoadType(rawData().GetRoadType());
|
||||
|
||||
@@ -64,20 +66,21 @@ static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType) {
|
||||
_locationCoordinate = CLLocationCoordinate2DMake(latlon.m_lat, latlon.m_lon);
|
||||
|
||||
NSMutableArray * tagsArray = [NSMutableArray array];
|
||||
for (auto const & s : rawData().GetRawTypes()) {
|
||||
for (auto const & s : rawData().GetRawTypes())
|
||||
[tagsArray addObject:@(s.c_str())];
|
||||
}
|
||||
|
||||
if (rawData().IsTrack()) {
|
||||
if (rawData().IsTrack())
|
||||
{
|
||||
__weak auto weakSelf = self;
|
||||
_trackData = [[PlacePageTrackData alloc] initWithRawData:rawData() onActivePointChanged:^(void) {
|
||||
[weakSelf handleActiveTrackSelectionPointChanged];
|
||||
}];
|
||||
_trackData =
|
||||
[[PlacePageTrackData alloc] initWithRawData:rawData()
|
||||
onActivePointChanged:^(void) { [weakSelf handleActiveTrackSelectionPointChanged]; }];
|
||||
}
|
||||
_previewData = [[PlacePagePreviewData alloc] initWithRawData:rawData()];
|
||||
|
||||
auto const & countryId = rawData().GetCountryId();
|
||||
if (!countryId.empty()) {
|
||||
if (!countryId.empty())
|
||||
{
|
||||
_mapNodeAttributes = [[MWMStorage sharedStorage] attributesForCountry:@(rawData().GetCountryId().c_str())];
|
||||
[[MWMStorage sharedStorage] addObserver:self];
|
||||
}
|
||||
@@ -91,23 +94,27 @@ static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTrackInfo:(TrackInfo * _Nonnull)trackInfo elevationInfo:(ElevationProfileData * _Nullable)elevationInfo {
|
||||
- (instancetype)initWithTrackInfo:(TrackInfo * _Nonnull)trackInfo
|
||||
elevationInfo:(ElevationProfileData * _Nullable)elevationInfo
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_objectType = PlacePageObjectTypeTrackRecording;
|
||||
_roadType = PlacePageRoadTypeNone;
|
||||
_previewData = [[PlacePagePreviewData alloc] initWithTrackInfo:trackInfo];
|
||||
__weak auto weakSelf = self;
|
||||
_trackData = [[PlacePageTrackData alloc] initWithTrackInfo:trackInfo
|
||||
_trackData =
|
||||
[[PlacePageTrackData alloc] initWithTrackInfo:trackInfo
|
||||
elevationInfo:elevationInfo
|
||||
onActivePointChanged:^(void) {
|
||||
[weakSelf handleActiveTrackSelectionPointChanged];
|
||||
}];
|
||||
onActivePointChanged:^(void) { [weakSelf handleActiveTrackSelectionPointChanged]; }];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateWithTrackInfo:(TrackInfo * _Nonnull)trackInfo elevationInfo:(ElevationProfileData * _Nullable)elevationInfo {
|
||||
- (void)updateWithTrackInfo:(TrackInfo * _Nonnull)trackInfo
|
||||
elevationInfo:(ElevationProfileData * _Nullable)elevationInfo
|
||||
{
|
||||
_previewData = [[PlacePagePreviewData alloc] initWithTrackInfo:trackInfo];
|
||||
_trackData.trackInfo = trackInfo;
|
||||
_trackData.elevationProfileData = elevationInfo;
|
||||
@@ -115,7 +122,8 @@ static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType) {
|
||||
self.onTrackRecordingProgressUpdate();
|
||||
}
|
||||
|
||||
- (void)handleActiveTrackSelectionPointChanged {
|
||||
- (void)handleActiveTrackSelectionPointChanged
|
||||
{
|
||||
if (!self || !rawData().IsTrack())
|
||||
return;
|
||||
auto const & trackInfo = GetFramework().GetBookmarkManager().GetTrackSelectionInfo(rawData().GetTrackId());
|
||||
@@ -124,66 +132,72 @@ static PlacePageRoadType convertRoadType(RoadWarningMarkType roadType) {
|
||||
self.previewData = [[PlacePagePreviewData alloc] initWithRawData:rawData()];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
if (self.mapNodeAttributes != nil) {
|
||||
- (void)dealloc
|
||||
{
|
||||
if (self.mapNodeAttributes != nil)
|
||||
[[MWMStorage sharedStorage] removeObserver:self];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)hasData {
|
||||
+ (BOOL)hasData
|
||||
{
|
||||
return GetFramework().HasPlacePageInfo();
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)updateBookmarkStatus {
|
||||
if (!GetFramework().HasPlacePageInfo()) {
|
||||
- (void)updateBookmarkStatus
|
||||
{
|
||||
if (!GetFramework().HasPlacePageInfo())
|
||||
return;
|
||||
}
|
||||
if (rawData().IsBookmark()) {
|
||||
if (rawData().IsBookmark())
|
||||
{
|
||||
_bookmarkData = [[PlacePageBookmarkData alloc] initWithRawData:rawData()];
|
||||
} else if (rawData().IsTrack()) {
|
||||
}
|
||||
else if (rawData().IsTrack())
|
||||
{
|
||||
__weak auto weakSelf = self;
|
||||
_trackData = [[PlacePageTrackData alloc] initWithRawData:rawData() onActivePointChanged:^(void) {
|
||||
[weakSelf handleActiveTrackSelectionPointChanged];
|
||||
}];
|
||||
} else {
|
||||
_trackData =
|
||||
[[PlacePageTrackData alloc] initWithRawData:rawData()
|
||||
onActivePointChanged:^(void) { [weakSelf handleActiveTrackSelectionPointChanged]; }];
|
||||
}
|
||||
else
|
||||
{
|
||||
_bookmarkData = nil;
|
||||
}
|
||||
_previewData = [[PlacePagePreviewData alloc] initWithRawData:rawData()];
|
||||
_objectType = [self objectTypeFromRawData];
|
||||
if (self.onBookmarkStatusUpdate != nil) {
|
||||
if (self.onBookmarkStatusUpdate != nil)
|
||||
self.onBookmarkStatusUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
- (PlacePageObjectType)objectTypeFromRawData {
|
||||
if (rawData().IsBookmark()) {
|
||||
- (PlacePageObjectType)objectTypeFromRawData
|
||||
{
|
||||
if (rawData().IsBookmark())
|
||||
return PlacePageObjectTypeBookmark;
|
||||
} else if (rawData().IsTrack()) {
|
||||
else if (rawData().IsTrack())
|
||||
return PlacePageObjectTypeTrack;
|
||||
} else if (self.trackData) {
|
||||
else if (self.trackData)
|
||||
return PlacePageObjectTypeTrackRecording;
|
||||
} else {
|
||||
else
|
||||
return PlacePageObjectTypePOI;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - MWMStorageObserver
|
||||
|
||||
- (void)processCountryEvent:(NSString *)countryId {
|
||||
if ([countryId isEqualToString:self.mapNodeAttributes.countryId]) {
|
||||
- (void)processCountryEvent:(NSString *)countryId
|
||||
{
|
||||
if ([countryId isEqualToString:self.mapNodeAttributes.countryId])
|
||||
{
|
||||
_mapNodeAttributes = [[MWMStorage sharedStorage] attributesForCountry:countryId];
|
||||
if (self.onMapNodeStatusUpdate != nil) {
|
||||
if (self.onMapNodeStatusUpdate != nil)
|
||||
self.onMapNodeStatusUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processCountry:(NSString *)countryId downloadedBytes:(uint64_t)downloadedBytes totalBytes:(uint64_t)totalBytes {
|
||||
if ([countryId isEqualToString:self.mapNodeAttributes.countryId] && self.onMapNodeProgressUpdate != nil) {
|
||||
- (void)processCountry:(NSString *)countryId downloadedBytes:(uint64_t)downloadedBytes totalBytes:(uint64_t)totalBytes
|
||||
{
|
||||
if ([countryId isEqualToString:self.mapNodeAttributes.countryId] && self.onMapNodeProgressUpdate != nil)
|
||||
self.onMapNodeProgressUpdate(downloadedBytes, totalBytes);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
#import "MWMMapNodeAttributes+Core.h"
|
||||
#include <CoreApi/Framework.h>
|
||||
#import "MWMMapNodeAttributes+Core.h"
|
||||
|
||||
static MWMMapNodeStatus convertStatus(storage::NodeStatus status) {
|
||||
switch (status) {
|
||||
case storage::NodeStatus::Undefined:
|
||||
return MWMMapNodeStatusUndefined;
|
||||
case storage::NodeStatus::Downloading:
|
||||
return MWMMapNodeStatusDownloading;
|
||||
case storage::NodeStatus::Applying:
|
||||
return MWMMapNodeStatusApplying;
|
||||
case storage::NodeStatus::InQueue:
|
||||
return MWMMapNodeStatusInQueue;
|
||||
case storage::NodeStatus::Error:
|
||||
return MWMMapNodeStatusError;
|
||||
case storage::NodeStatus::OnDiskOutOfDate:
|
||||
return MWMMapNodeStatusOnDiskOutOfDate;
|
||||
case storage::NodeStatus::OnDisk:
|
||||
return MWMMapNodeStatusOnDisk;
|
||||
case storage::NodeStatus::NotDownloaded:
|
||||
return MWMMapNodeStatusNotDownloaded;
|
||||
case storage::NodeStatus::Partly:
|
||||
return MWMMapNodeStatusPartly;
|
||||
static MWMMapNodeStatus convertStatus(storage::NodeStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case storage::NodeStatus::Undefined: return MWMMapNodeStatusUndefined;
|
||||
case storage::NodeStatus::Downloading: return MWMMapNodeStatusDownloading;
|
||||
case storage::NodeStatus::Applying: return MWMMapNodeStatusApplying;
|
||||
case storage::NodeStatus::InQueue: return MWMMapNodeStatusInQueue;
|
||||
case storage::NodeStatus::Error: return MWMMapNodeStatusError;
|
||||
case storage::NodeStatus::OnDiskOutOfDate: return MWMMapNodeStatusOnDiskOutOfDate;
|
||||
case storage::NodeStatus::OnDisk: return MWMMapNodeStatusOnDisk;
|
||||
case storage::NodeStatus::NotDownloaded: return MWMMapNodeStatusNotDownloaded;
|
||||
case storage::NodeStatus::Partly: return MWMMapNodeStatusPartly;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,18 +26,22 @@ static MWMMapNodeStatus convertStatus(storage::NodeStatus status) {
|
||||
|
||||
@implementation MWMCountryIdAndName
|
||||
|
||||
- (instancetype)initWithCountryId:(NSString *)countryId name:(NSString *)countryName {
|
||||
- (instancetype)initWithCountryId:(NSString *)countryId name:(NSString *)countryName
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_countryId = countryId;
|
||||
_countryName = countryName;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCountryAndName:(storage::CountryIdAndName const &)countryAndName {
|
||||
- (instancetype)initWithCountryAndName:(storage::CountryIdAndName const &)countryAndName
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_countryId = @(countryAndName.m_id.c_str());
|
||||
_countryName = @(countryAndName.m_localName.c_str());
|
||||
}
|
||||
@@ -62,9 +59,11 @@ static MWMMapNodeStatus convertStatus(storage::NodeStatus status) {
|
||||
- (instancetype)initWithCoreAttributes:(storage::NodeAttrs const &)attributes
|
||||
countryId:(NSString *)countryId
|
||||
hasParent:(BOOL)hasParent
|
||||
hasChildren:(BOOL)hasChildren {
|
||||
hasChildren:(BOOL)hasChildren
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_countryId = [countryId copy];
|
||||
_totalMwmCount = attributes.m_mwmCounter;
|
||||
_downloadedMwmCount = attributes.m_localMwmCounter;
|
||||
@@ -79,21 +78,22 @@ static MWMMapNodeStatus convertStatus(storage::NodeStatus status) {
|
||||
_hasParent = hasParent;
|
||||
|
||||
storage::Storage::UpdateInfo updateInfo;
|
||||
if (GetFramework().GetStorage().GetUpdateInfo([countryId UTF8String], updateInfo)) {
|
||||
if (GetFramework().GetStorage().GetUpdateInfo([countryId UTF8String], updateInfo))
|
||||
_totalUpdateSizeBytes = updateInfo.m_totalDownloadSizeInBytes;
|
||||
} else {
|
||||
else
|
||||
_totalUpdateSizeBytes = 0;
|
||||
}
|
||||
|
||||
NSMutableArray * parentInfoArray = [NSMutableArray arrayWithCapacity:attributes.m_parentInfo.size()];
|
||||
for (auto const &pi : attributes.m_parentInfo) {
|
||||
for (auto const & pi : attributes.m_parentInfo)
|
||||
{
|
||||
MWMCountryIdAndName * cn = [[MWMCountryIdAndName alloc] initWithCountryAndName:pi];
|
||||
[parentInfoArray addObject:cn];
|
||||
}
|
||||
_parentInfo = [parentInfoArray copy];
|
||||
|
||||
NSMutableArray * topmostInfoArray = [NSMutableArray arrayWithCapacity:attributes.m_topmostParentInfo.size()];
|
||||
for (auto const &pi : attributes.m_topmostParentInfo) {
|
||||
for (auto const & pi : attributes.m_topmostParentInfo)
|
||||
{
|
||||
MWMCountryIdAndName * cn = [[MWMCountryIdAndName alloc] initWithCountryAndName:pi];
|
||||
[topmostInfoArray addObject:cn];
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
@implementation MWMMapSearchResult (Core)
|
||||
|
||||
- (instancetype)initWithSearchResult:(storage::DownloaderSearchResult const &)searchResult {
|
||||
- (instancetype)initWithSearchResult:(storage::DownloaderSearchResult const &)searchResult
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_countryId = @(searchResult.m_countryId.c_str());
|
||||
_matchedName = @(searchResult.m_matchedName.c_str());
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
@implementation MWMMapUpdateInfo (Core)
|
||||
|
||||
- (instancetype)initWithUpdateInfo:(storage::Storage::UpdateInfo const &)updateInfo {
|
||||
- (instancetype)initWithUpdateInfo:(storage::Storage::UpdateInfo const &)updateInfo
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_numberOfFiles = updateInfo.m_numberOfMwmFilesToUpdate;
|
||||
_updateSize = updateInfo.m_totalDownloadSizeInBytes;
|
||||
_differenceSize = updateInfo.m_sizeDifference;
|
||||
|
||||
@@ -25,35 +25,38 @@ using namespace storage;
|
||||
|
||||
@implementation MWMStorage
|
||||
|
||||
+ (instancetype)sharedStorage {
|
||||
+ (instancetype)sharedStorage
|
||||
{
|
||||
static MWMStorage * instance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[self alloc] init];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; });
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_observers = [NSHashTable weakObjectsHashTable];
|
||||
NSHashTable * observers = _observers;
|
||||
|
||||
GetFramework().GetStorage().Subscribe(
|
||||
[observers](CountryId const & countryId) {
|
||||
[observers](CountryId const & countryId)
|
||||
{
|
||||
// A copy is created, because MWMMapDownloadDialog is unsubscribed inside this notification with
|
||||
// NSGenericException', reason: '*** Collection <NSConcreteHashTable> was mutated while being enumerated.'
|
||||
NSHashTable * observersCopy = [observers copy];
|
||||
for (id<MWMStorageObserver> observer in observersCopy) {
|
||||
for (id<MWMStorageObserver> observer in observersCopy)
|
||||
[observer processCountryEvent:@(countryId.c_str())];
|
||||
}
|
||||
},
|
||||
[observers](CountryId const & countryId, downloader::Progress const & progress) {
|
||||
for (id<MWMStorageObserver> observer in observers) {
|
||||
}, [observers](CountryId const & countryId, downloader::Progress const & progress)
|
||||
{
|
||||
for (id<MWMStorageObserver> observer in observers)
|
||||
{
|
||||
// processCountry function in observer's implementation may not exist.
|
||||
/// @todo We can face with an invisible bug, if function's signature will be changed.
|
||||
if ([observer respondsToSelector:@selector(processCountry:downloadedBytes:totalBytes:)]) {
|
||||
if ([observer respondsToSelector:@selector(processCountry:downloadedBytes:totalBytes:)])
|
||||
{
|
||||
[observer processCountry:@(countryId.c_str())
|
||||
downloadedBytes:progress.m_bytesDownloaded
|
||||
totalBytes:progress.m_bytesTotal];
|
||||
@@ -64,47 +67,62 @@ using namespace storage;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addObserver:(id<MWMStorageObserver>)observer {
|
||||
- (void)addObserver:(id<MWMStorageObserver>)observer
|
||||
{
|
||||
[self.observers addObject:observer];
|
||||
}
|
||||
|
||||
- (void)removeObserver:(id<MWMStorageObserver>)observer {
|
||||
- (void)removeObserver:(id<MWMStorageObserver>)observer
|
||||
{
|
||||
[self.observers removeObject:observer];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)downloadNode:(NSString *)countryId error:(NSError *__autoreleasing _Nullable *)error {
|
||||
if (IsEnoughSpaceForDownload(countryId.UTF8String, GetFramework().GetStorage())) {
|
||||
- (BOOL)downloadNode:(NSString *)countryId error:(NSError * __autoreleasing _Nullable *)error
|
||||
{
|
||||
if (IsEnoughSpaceForDownload(countryId.UTF8String, GetFramework().GetStorage()))
|
||||
{
|
||||
NSError * connectionError;
|
||||
if ([self checkConnection:&connectionError]) {
|
||||
if ([self checkConnection:&connectionError])
|
||||
{
|
||||
GetFramework().GetStorage().DownloadNode(countryId.UTF8String);
|
||||
return YES;
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
*error = connectionError;
|
||||
}
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageNotEnoughSpace userInfo:nil];
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)retryDownloadNode:(NSString *)countryId {
|
||||
if ([self checkConnection:nil]) {
|
||||
- (void)retryDownloadNode:(NSString *)countryId
|
||||
{
|
||||
if ([self checkConnection:nil])
|
||||
GetFramework().GetStorage().RetryDownloadNode(countryId.UTF8String);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)updateNode:(NSString *)countryId error:(NSError *__autoreleasing _Nullable *)error {
|
||||
if (IsEnoughSpaceForUpdate(countryId.UTF8String, GetFramework().GetStorage())) {
|
||||
- (BOOL)updateNode:(NSString *)countryId error:(NSError * __autoreleasing _Nullable *)error
|
||||
{
|
||||
if (IsEnoughSpaceForUpdate(countryId.UTF8String, GetFramework().GetStorage()))
|
||||
{
|
||||
NSError * connectionError;
|
||||
if ([self checkConnection:&connectionError]) {
|
||||
if ([self checkConnection:&connectionError])
|
||||
{
|
||||
GetFramework().GetStorage().UpdateNode(countryId.UTF8String);
|
||||
return YES;
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
*error = connectionError;
|
||||
}
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageNotEnoughSpace userInfo:nil];
|
||||
}
|
||||
|
||||
@@ -113,20 +131,23 @@ using namespace storage;
|
||||
|
||||
- (BOOL)deleteNode:(NSString *)countryId
|
||||
ignoreUnsavedEdits:(BOOL)force
|
||||
error:(NSError *__autoreleasing _Nullable *)error {
|
||||
error:(NSError * __autoreleasing _Nullable *)error
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
if (f.GetRoutingManager().IsRoutingActive()) {
|
||||
if (error) {
|
||||
if (f.GetRoutingManager().IsRoutingActive())
|
||||
{
|
||||
if (error)
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageRoutingActive userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!force && f.HasUnsavedEdits(countryId.UTF8String)) {
|
||||
if (error) {
|
||||
if (!force && f.HasUnsavedEdits(countryId.UTF8String))
|
||||
{
|
||||
if (error)
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageHaveUnsavedEdits userInfo:nil];
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
f.GetStorage().DeleteNode(countryId.UTF8String);
|
||||
return YES;
|
||||
}
|
||||
@@ -134,65 +155,76 @@ using namespace storage;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)cancelDownloadNode:(NSString *)countryId {
|
||||
- (void)cancelDownloadNode:(NSString *)countryId
|
||||
{
|
||||
GetFramework().GetStorage().CancelDownloadNode(countryId.UTF8String);
|
||||
}
|
||||
|
||||
- (void)showNode:(NSString *)countryId {
|
||||
- (void)showNode:(NSString *)countryId
|
||||
{
|
||||
GetFramework().ShowNode(countryId.UTF8String);
|
||||
}
|
||||
|
||||
- (BOOL)downloadNodes:(NSArray<NSString *> *)countryIds error:(NSError *__autoreleasing _Nullable *)error {
|
||||
- (BOOL)downloadNodes:(NSArray<NSString *> *)countryIds error:(NSError * __autoreleasing _Nullable *)error
|
||||
{
|
||||
auto & s = GetFramework().GetStorage();
|
||||
|
||||
MwmSize requiredSize = 0;
|
||||
for (NSString *countryId in countryIds) {
|
||||
for (NSString * countryId in countryIds)
|
||||
{
|
||||
NodeAttrs nodeAttrs;
|
||||
GetFramework().GetStorage().GetNodeAttrs(countryId.UTF8String, nodeAttrs);
|
||||
requiredSize += nodeAttrs.m_mwmSize;
|
||||
}
|
||||
|
||||
if (storage::IsEnoughSpaceForDownload(requiredSize)) {
|
||||
if (storage::IsEnoughSpaceForDownload(requiredSize))
|
||||
{
|
||||
NSError * connectionError;
|
||||
if ([self checkConnection:&connectionError]) {
|
||||
for (NSString *countryId in countryIds) {
|
||||
if ([self checkConnection:&connectionError])
|
||||
{
|
||||
for (NSString * countryId in countryIds)
|
||||
s.DownloadNode(countryId.UTF8String);
|
||||
}
|
||||
return YES;
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
*error = connectionError;
|
||||
}
|
||||
} else if (error) {
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageNotEnoughSpace userInfo:nil];
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)checkConnection:(NSError *__autoreleasing *)error {
|
||||
switch (Platform::ConnectionStatus()) {
|
||||
- (BOOL)checkConnection:(NSError * __autoreleasing *)error
|
||||
{
|
||||
switch (Platform::ConnectionStatus())
|
||||
{
|
||||
case Platform::EConnectionType::CONNECTION_NONE:
|
||||
if (error) {
|
||||
if (error)
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageNoConnection userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
break;
|
||||
case Platform::EConnectionType::CONNECTION_WIFI:
|
||||
if (error) {
|
||||
if (error)
|
||||
*error = nil;
|
||||
}
|
||||
return YES;
|
||||
break;
|
||||
case Platform::EConnectionType::CONNECTION_WWAN: {
|
||||
if (!GetFramework().GetDownloadingPolicy().IsCellularDownloadEnabled()) {
|
||||
if (error) {
|
||||
case Platform::EConnectionType::CONNECTION_WWAN:
|
||||
{
|
||||
if (!GetFramework().GetDownloadingPolicy().IsCellularDownloadEnabled())
|
||||
{
|
||||
if (error)
|
||||
*error = [NSError errorWithDomain:kStorageErrorDomain code:kStorageCellularForbidden userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
} else {
|
||||
if (error) {
|
||||
*error = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = nil;
|
||||
return YES;
|
||||
}
|
||||
break;
|
||||
@@ -200,68 +232,74 @@ using namespace storage;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)haveDownloadedCountries {
|
||||
- (BOOL)haveDownloadedCountries
|
||||
{
|
||||
return GetFramework().GetStorage().HaveDownloadedCountries();
|
||||
}
|
||||
|
||||
- (BOOL)downloadInProgress {
|
||||
- (BOOL)downloadInProgress
|
||||
{
|
||||
return GetFramework().GetStorage().IsDownloadInProgress();
|
||||
}
|
||||
|
||||
- (void)enableCellularDownload:(BOOL)enable {
|
||||
- (void)enableCellularDownload:(BOOL)enable
|
||||
{
|
||||
GetFramework().GetDownloadingPolicy().EnableCellularDownload(enable);
|
||||
}
|
||||
|
||||
#pragma mark - Attributes
|
||||
|
||||
- (NSArray<NSString *> *)allCountries {
|
||||
- (NSArray<NSString *> *)allCountries
|
||||
{
|
||||
NSString * rootId = @(GetFramework().GetStorage().GetRootId().c_str());
|
||||
return [self allCountriesWithParent:rootId];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)allCountriesWithParent:(NSString *)countryId {
|
||||
- (NSArray<NSString *> *)allCountriesWithParent:(NSString *)countryId
|
||||
{
|
||||
storage::CountriesVec downloadedChildren;
|
||||
storage::CountriesVec availableChildren;
|
||||
GetFramework().GetStorage().GetChildrenInGroups(countryId.UTF8String, downloadedChildren, availableChildren,
|
||||
true /* keepAvailableChildren */);
|
||||
|
||||
NSMutableArray * result = [NSMutableArray arrayWithCapacity:availableChildren.size()];
|
||||
for (auto const &cid : availableChildren) {
|
||||
for (auto const & cid : availableChildren)
|
||||
[result addObject:@(cid.c_str())];
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)availableCountriesWithParent:(NSString *)countryId {
|
||||
- (NSArray<NSString *> *)availableCountriesWithParent:(NSString *)countryId
|
||||
{
|
||||
storage::CountriesVec downloadedChildren;
|
||||
storage::CountriesVec availableChildren;
|
||||
GetFramework().GetStorage().GetChildrenInGroups(countryId.UTF8String, downloadedChildren, availableChildren);
|
||||
|
||||
NSMutableArray * result = [NSMutableArray arrayWithCapacity:availableChildren.size()];
|
||||
for (auto const &cid : availableChildren) {
|
||||
for (auto const & cid : availableChildren)
|
||||
[result addObject:@(cid.c_str())];
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)downloadedCountries {
|
||||
- (NSArray<NSString *> *)downloadedCountries
|
||||
{
|
||||
NSString * rootId = @(GetFramework().GetStorage().GetRootId().c_str());
|
||||
return [self downloadedCountriesWithParent:rootId];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)downloadedCountriesWithParent:(NSString *)countryId {
|
||||
- (NSArray<NSString *> *)downloadedCountriesWithParent:(NSString *)countryId
|
||||
{
|
||||
storage::CountriesVec downloadedChildren;
|
||||
storage::CountriesVec availableChildren;
|
||||
GetFramework().GetStorage().GetChildrenInGroups(countryId.UTF8String, downloadedChildren, availableChildren);
|
||||
|
||||
NSMutableArray * result = [NSMutableArray arrayWithCapacity:downloadedChildren.size()];
|
||||
for (auto const &cid : downloadedChildren) {
|
||||
for (auto const & cid : downloadedChildren)
|
||||
[result addObject:@(cid.c_str())];
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
- (MWMMapNodeAttributes *)attributesForCountry:(NSString *)countryId {
|
||||
- (MWMMapNodeAttributes *)attributesForCountry:(NSString *)countryId
|
||||
{
|
||||
auto const & s = GetFramework().GetStorage();
|
||||
storage::NodeAttrs nodeAttrs;
|
||||
s.GetNodeAttrs(countryId.UTF8String, nodeAttrs);
|
||||
@@ -274,25 +312,30 @@ using namespace storage;
|
||||
hasChildren:!children.empty()];
|
||||
}
|
||||
|
||||
- (MWMMapNodeAttributes *)attributesForRoot {
|
||||
- (MWMMapNodeAttributes *)attributesForRoot
|
||||
{
|
||||
return [self attributesForCountry:@(GetFramework().GetStorage().GetRootId().c_str())];
|
||||
}
|
||||
|
||||
- (NSString *)getRootId {
|
||||
- (NSString *)getRootId
|
||||
{
|
||||
return @(GetFramework().GetStorage().GetRootId().c_str());
|
||||
}
|
||||
|
||||
- (NSString *)nameForCountry:(NSString *)countryId {
|
||||
- (NSString *)nameForCountry:(NSString *)countryId
|
||||
{
|
||||
return @(GetFramework().GetStorage().GetNodeLocalName(countryId.UTF8String).c_str());
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)nearbyAvailableCountries:(CLLocationCoordinate2D)location {
|
||||
- (NSArray<NSString *> *)nearbyAvailableCountries:(CLLocationCoordinate2D)location
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
storage::CountriesVec closestCoutryIds;
|
||||
f.GetCountryInfoGetter().GetRegionsCountryId(mercator::FromLatLon(location.latitude, location.longitude),
|
||||
closestCoutryIds);
|
||||
NSMutableArray * nearmeCountries = [NSMutableArray array];
|
||||
for (auto const &countryId : closestCoutryIds) {
|
||||
for (auto const & countryId : closestCoutryIds)
|
||||
{
|
||||
storage::NodeStatuses nodeStatuses;
|
||||
f.GetStorage().GetNodeStatuses(countryId, nodeStatuses);
|
||||
if (nodeStatuses.m_status != storage::NodeStatus::OnDisk)
|
||||
@@ -302,14 +345,14 @@ using namespace storage;
|
||||
return nearmeCountries.count > 0 ? [nearmeCountries copy] : nil;
|
||||
}
|
||||
|
||||
- (MWMMapUpdateInfo *)updateInfoWithParent:(nullable NSString *)countryId {
|
||||
- (MWMMapUpdateInfo *)updateInfoWithParent:(nullable NSString *)countryId
|
||||
{
|
||||
auto const & s = GetFramework().GetStorage();
|
||||
Storage::UpdateInfo updateInfo;
|
||||
if (countryId.length > 0) {
|
||||
if (countryId.length > 0)
|
||||
s.GetUpdateInfo(countryId.UTF8String, updateInfo);
|
||||
} else {
|
||||
else
|
||||
s.GetUpdateInfo(s.GetRootId(), updateInfo);
|
||||
}
|
||||
return [[MWMMapUpdateInfo alloc] initWithUpdateInfo:updateInfo];
|
||||
}
|
||||
|
||||
|
||||
@@ -15,46 +15,45 @@ static NSString *didChangeOutdoorMapStyle = @"didChangeOutdoorMapStyle";
|
||||
|
||||
#pragma mark - Instance
|
||||
|
||||
+ (MWMMapOverlayManager *)manager {
|
||||
+ (MWMMapOverlayManager *)manager
|
||||
{
|
||||
static MWMMapOverlayManager * manager;
|
||||
static dispatch_once_t onceToken = 0;
|
||||
dispatch_once(&onceToken, ^{
|
||||
manager = [[self alloc] initManager];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ manager = [[self alloc] initManager]; });
|
||||
return manager;
|
||||
}
|
||||
|
||||
- (instancetype)initManager {
|
||||
- (instancetype)initManager
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_observers = [NSHashTable weakObjectsHashTable];
|
||||
GetFramework().GetTrafficManager().SetStateListener([self](TrafficManager::TrafficState state) {
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers) {
|
||||
if ([observer respondsToSelector:@selector(onTrafficStateUpdated)]) {
|
||||
GetFramework().GetTrafficManager().SetStateListener([self](TrafficManager::TrafficState state)
|
||||
{
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onTrafficStateUpdated)])
|
||||
[observer onTrafficStateUpdated];
|
||||
}
|
||||
}
|
||||
});
|
||||
GetFramework().GetTransitManager().SetStateListener([self](TransitReadManager::TransitSchemeState state) {
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers) {
|
||||
if ([observer respondsToSelector:@selector(onTransitStateUpdated)]) {
|
||||
GetFramework().GetTransitManager().SetStateListener([self](TransitReadManager::TransitSchemeState state)
|
||||
{
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onTransitStateUpdated)])
|
||||
[observer onTransitStateUpdated];
|
||||
}
|
||||
}
|
||||
});
|
||||
GetFramework().GetIsolinesManager().SetStateListener([self](IsolinesManager::IsolinesState state) {
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers) {
|
||||
if ([observer respondsToSelector:@selector(onIsoLinesStateUpdated)]) {
|
||||
GetFramework().GetIsolinesManager().SetStateListener([self](IsolinesManager::IsolinesState state)
|
||||
{
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onIsoLinesStateUpdated)])
|
||||
[observer onIsoLinesStateUpdated];
|
||||
}
|
||||
}
|
||||
});
|
||||
[NSNotificationCenter.defaultCenter addObserverForName:didChangeOutdoorMapStyle object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) {
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers) {
|
||||
if ([observer respondsToSelector:@selector(onOutdoorStateUpdated)]) {
|
||||
[NSNotificationCenter.defaultCenter addObserverForName:didChangeOutdoorMapStyle
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification * _Nonnull notification) {
|
||||
for (id<MWMMapOverlayManagerObserver> observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onOutdoorStateUpdated)])
|
||||
[observer onOutdoorStateUpdated];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
@@ -62,93 +61,93 @@ static NSString *didChangeOutdoorMapStyle = @"didChangeOutdoorMapStyle";
|
||||
|
||||
#pragma mark - Add/Remove Observers
|
||||
|
||||
+ (void)addObserver:(id<MWMMapOverlayManagerObserver>)observer {
|
||||
+ (void)addObserver:(id<MWMMapOverlayManagerObserver>)observer
|
||||
{
|
||||
[[MWMMapOverlayManager manager].observers addObject:observer];
|
||||
}
|
||||
|
||||
+ (void)removeObserver:(id<MWMMapOverlayManagerObserver>)observer {
|
||||
+ (void)removeObserver:(id<MWMMapOverlayManagerObserver>)observer
|
||||
{
|
||||
[[MWMMapOverlayManager manager].observers removeObject:observer];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
+ (MWMMapOverlayTrafficState)trafficState {
|
||||
switch (GetFramework().GetTrafficManager().GetState()) {
|
||||
case TrafficManager::TrafficState::Disabled:
|
||||
return MWMMapOverlayTrafficStateDisabled;
|
||||
case TrafficManager::TrafficState::Enabled:
|
||||
return MWMMapOverlayTrafficStateEnabled;
|
||||
case TrafficManager::TrafficState::WaitingData:
|
||||
return MWMMapOverlayTrafficStateWaitingData;
|
||||
case TrafficManager::TrafficState::Outdated:
|
||||
return MWMMapOverlayTrafficStateOutdated;
|
||||
case TrafficManager::TrafficState::NoData:
|
||||
return MWMMapOverlayTrafficStateNoData;
|
||||
case TrafficManager::TrafficState::NetworkError:
|
||||
return MWMMapOverlayTrafficStateNetworkError;
|
||||
case TrafficManager::TrafficState::ExpiredData:
|
||||
return MWMMapOverlayTrafficStateExpiredData;
|
||||
case TrafficManager::TrafficState::ExpiredApp:
|
||||
return MWMMapOverlayTrafficStateExpiredApp;
|
||||
+ (MWMMapOverlayTrafficState)trafficState
|
||||
{
|
||||
switch (GetFramework().GetTrafficManager().GetState())
|
||||
{
|
||||
case TrafficManager::TrafficState::Disabled: return MWMMapOverlayTrafficStateDisabled;
|
||||
case TrafficManager::TrafficState::Enabled: return MWMMapOverlayTrafficStateEnabled;
|
||||
case TrafficManager::TrafficState::WaitingData: return MWMMapOverlayTrafficStateWaitingData;
|
||||
case TrafficManager::TrafficState::Outdated: return MWMMapOverlayTrafficStateOutdated;
|
||||
case TrafficManager::TrafficState::NoData: return MWMMapOverlayTrafficStateNoData;
|
||||
case TrafficManager::TrafficState::NetworkError: return MWMMapOverlayTrafficStateNetworkError;
|
||||
case TrafficManager::TrafficState::ExpiredData: return MWMMapOverlayTrafficStateExpiredData;
|
||||
case TrafficManager::TrafficState::ExpiredApp: return MWMMapOverlayTrafficStateExpiredApp;
|
||||
}
|
||||
}
|
||||
|
||||
+ (MWMMapOverlayTransitState)transitState {
|
||||
switch (GetFramework().GetTransitManager().GetState()) {
|
||||
case TransitReadManager::TransitSchemeState::Disabled:
|
||||
return MWMMapOverlayTransitStateDisabled;
|
||||
case TransitReadManager::TransitSchemeState::Enabled:
|
||||
return MWMMapOverlayTransitStateEnabled;
|
||||
case TransitReadManager::TransitSchemeState::NoData:
|
||||
return MWMMapOverlayTransitStateNoData;
|
||||
+ (MWMMapOverlayTransitState)transitState
|
||||
{
|
||||
switch (GetFramework().GetTransitManager().GetState())
|
||||
{
|
||||
case TransitReadManager::TransitSchemeState::Disabled: return MWMMapOverlayTransitStateDisabled;
|
||||
case TransitReadManager::TransitSchemeState::Enabled: return MWMMapOverlayTransitStateEnabled;
|
||||
case TransitReadManager::TransitSchemeState::NoData: return MWMMapOverlayTransitStateNoData;
|
||||
}
|
||||
}
|
||||
|
||||
+ (MWMMapOverlayIsolinesState)isolinesState {
|
||||
switch (GetFramework().GetIsolinesManager().GetState()) {
|
||||
case IsolinesManager::IsolinesState::Disabled:
|
||||
return MWMMapOverlayIsolinesStateDisabled;
|
||||
case IsolinesManager::IsolinesState::Enabled:
|
||||
return MWMMapOverlayIsolinesStateEnabled;
|
||||
case IsolinesManager::IsolinesState::ExpiredData:
|
||||
return MWMMapOverlayIsolinesStateExpiredData;
|
||||
case IsolinesManager::IsolinesState::NoData:
|
||||
return MWMMapOverlayIsolinesStateNoData;
|
||||
+ (MWMMapOverlayIsolinesState)isolinesState
|
||||
{
|
||||
switch (GetFramework().GetIsolinesManager().GetState())
|
||||
{
|
||||
case IsolinesManager::IsolinesState::Disabled: return MWMMapOverlayIsolinesStateDisabled;
|
||||
case IsolinesManager::IsolinesState::Enabled: return MWMMapOverlayIsolinesStateEnabled;
|
||||
case IsolinesManager::IsolinesState::ExpiredData: return MWMMapOverlayIsolinesStateExpiredData;
|
||||
case IsolinesManager::IsolinesState::NoData: return MWMMapOverlayIsolinesStateNoData;
|
||||
}
|
||||
}
|
||||
|
||||
+ (MWMMapOverlayOutdoorState)outdoorState {
|
||||
switch (GetFramework().GetMapStyle()) {
|
||||
+ (MWMMapOverlayOutdoorState)outdoorState
|
||||
{
|
||||
switch (GetFramework().GetMapStyle())
|
||||
{
|
||||
case MapStyleOutdoorsLight:
|
||||
case MapStyleOutdoorsDark:
|
||||
return MWMMapOverlayOutdoorStateEnabled;
|
||||
default:
|
||||
return MWMMapOverlayOutdoorStateDisabled;
|
||||
case MapStyleOutdoorsDark: return MWMMapOverlayOutdoorStateEnabled;
|
||||
default: return MWMMapOverlayOutdoorStateDisabled;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)trafficEnabled {
|
||||
+ (BOOL)trafficEnabled
|
||||
{
|
||||
return self.trafficState != MWMMapOverlayTrafficStateDisabled;
|
||||
}
|
||||
|
||||
+ (BOOL)transitEnabled {
|
||||
+ (BOOL)transitEnabled
|
||||
{
|
||||
return self.transitState != MWMMapOverlayTransitStateDisabled;
|
||||
}
|
||||
|
||||
+ (BOOL)isoLinesEnabled {
|
||||
+ (BOOL)isoLinesEnabled
|
||||
{
|
||||
return self.isolinesState != MWMMapOverlayIsolinesStateDisabled;
|
||||
}
|
||||
|
||||
+ (BOOL)isolinesVisible {
|
||||
+ (BOOL)isolinesVisible
|
||||
{
|
||||
return GetFramework().GetIsolinesManager().IsVisible();
|
||||
}
|
||||
|
||||
+ (BOOL)outdoorEnabled {
|
||||
+ (BOOL)outdoorEnabled
|
||||
{
|
||||
return self.outdoorState != MWMMapOverlayOutdoorStateDisabled;
|
||||
}
|
||||
|
||||
+ (void)setTrafficEnabled:(BOOL)enable {
|
||||
if (enable) {
|
||||
+ (void)setTrafficEnabled:(BOOL)enable
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
[self setTransitEnabled:false];
|
||||
[self setIsoLinesEnabled:false];
|
||||
}
|
||||
@@ -158,8 +157,10 @@ static NSString *didChangeOutdoorMapStyle = @"didChangeOutdoorMapStyle";
|
||||
f.SaveTrafficEnabled(enable);
|
||||
}
|
||||
|
||||
+ (void)setTransitEnabled:(BOOL)enable {
|
||||
if (enable) {
|
||||
+ (void)setTransitEnabled:(BOOL)enable
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
[self setTrafficEnabled:!enable];
|
||||
[self setIsoLinesEnabled:false];
|
||||
[self setOutdoorEnabled:false];
|
||||
@@ -170,8 +171,10 @@ static NSString *didChangeOutdoorMapStyle = @"didChangeOutdoorMapStyle";
|
||||
f.SaveTransitSchemeEnabled(enable);
|
||||
}
|
||||
|
||||
+ (void)setIsoLinesEnabled:(BOOL)enable {
|
||||
if (enable) {
|
||||
+ (void)setIsoLinesEnabled:(BOOL)enable
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
[self setTrafficEnabled:false];
|
||||
[self setTransitEnabled:false];
|
||||
}
|
||||
@@ -181,29 +184,28 @@ static NSString *didChangeOutdoorMapStyle = @"didChangeOutdoorMapStyle";
|
||||
f.SaveIsolinesEnabled(enable);
|
||||
}
|
||||
|
||||
+ (void)setOutdoorEnabled:(BOOL)enable {
|
||||
if (enable) {
|
||||
+ (void)setOutdoorEnabled:(BOOL)enable
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
[self setTransitEnabled:false];
|
||||
[self setTrafficEnabled:false];
|
||||
}
|
||||
|
||||
auto & f = GetFramework();
|
||||
switch (f.GetMapStyle()) {
|
||||
switch (f.GetMapStyle())
|
||||
{
|
||||
case MapStyleDefaultLight:
|
||||
case MapStyleVehicleLight:
|
||||
case MapStyleOutdoorsLight:
|
||||
f.SetMapStyle(enable ? MapStyleOutdoorsLight : MapStyleDefaultLight);
|
||||
break;
|
||||
case MapStyleOutdoorsLight: f.SetMapStyle(enable ? MapStyleOutdoorsLight : MapStyleDefaultLight); break;
|
||||
case MapStyleDefaultDark:
|
||||
case MapStyleVehicleDark:
|
||||
case MapStyleOutdoorsDark:
|
||||
f.SetMapStyle(enable ? MapStyleOutdoorsDark : MapStyleDefaultDark);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case MapStyleOutdoorsDark: f.SetMapStyle(enable ? MapStyleOutdoorsDark : MapStyleDefaultDark); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// TODO: - Observing for the selected/deselected state of the Outdoor style should be implemented not by NSNotificationCenter but the same way as for IsoLines with 'GetFramework().GetIsolinesManager().SetStateListener'.
|
||||
// TODO: - Observing for the selected/deselected state of the Outdoor style should be implemented not by
|
||||
// NSNotificationCenter but the same way as for IsoLines with 'GetFramework().GetIsolinesManager().SetStateListener'.
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:didChangeOutdoorMapStyle object:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
@implementation CLLocation (Mercator)
|
||||
|
||||
- (m2::PointD)mercator { return location_helpers::ToMercator(self.coordinate); }
|
||||
- (m2::PointD)mercator
|
||||
{
|
||||
return location_helpers::ToMercator(self.coordinate);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,13 +21,16 @@
|
||||
|
||||
@implementation MWMCarPlaySearchResultObject
|
||||
|
||||
- (instancetype)initForRow:(NSInteger)row {
|
||||
- (instancetype)initForRow:(NSInteger)row
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
self.originalRow = row;
|
||||
NSInteger containerIndex = [MWMSearch containerIndexWithRow:row];
|
||||
SearchItemType type = [MWMSearch resultTypeWithRow:row];
|
||||
if (type == SearchItemTypeRegular) {
|
||||
if (type == SearchItemTypeRegular)
|
||||
{
|
||||
auto const & result = [MWMSearch resultWithContainerIndex:containerIndex];
|
||||
self.title = result.titleText;
|
||||
self.address = result.addressText;
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
API_AVAILABLE(ios(12.0))
|
||||
@interface MWMCarPlaySearchService () <MWMSearchObserver>
|
||||
@property(strong, nonatomic, nullable) void (^completionHandler)(NSArray<MWMCarPlaySearchResultObject *> *searchResults);
|
||||
@property(strong, nonatomic, nullable) void (^completionHandler)
|
||||
(NSArray<MWMCarPlaySearchResultObject *> * searchResults);
|
||||
@property(strong, nonatomic, nullable) NSString * lastQuery;
|
||||
@property(strong, nonatomic, nullable) NSString * inputLocale;
|
||||
@property(strong, nonatomic, readwrite) NSArray<MWMCarPlaySearchResultObject *> * lastResults;
|
||||
@@ -15,9 +16,11 @@ API_AVAILABLE(ios(12.0))
|
||||
|
||||
@implementation MWMCarPlaySearchService
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
[MWMSearch addObserver:self];
|
||||
self.lastResults = @[];
|
||||
}
|
||||
@@ -26,7 +29,8 @@ API_AVAILABLE(ios(12.0))
|
||||
|
||||
- (void)searchText:(NSString *)text
|
||||
forInputLocale:(NSString *)inputLocale
|
||||
completionHandler:(void (^)(NSArray<MWMCarPlaySearchResultObject *> *searchResults))completionHandler {
|
||||
completionHandler:(void (^)(NSArray<MWMCarPlaySearchResultObject *> * searchResults))completionHandler
|
||||
{
|
||||
self.lastQuery = text;
|
||||
self.inputLocale = inputLocale;
|
||||
self.lastResults = @[];
|
||||
@@ -36,24 +40,32 @@ API_AVAILABLE(ios(12.0))
|
||||
[MWMSearch searchQuery:query];
|
||||
}
|
||||
|
||||
- (void)saveLastQuery {
|
||||
if (self.lastQuery != nil && self.inputLocale != nil) {
|
||||
SearchQuery * query = [[SearchQuery alloc] init:self.lastQuery locale:self.inputLocale source:SearchTextSourceTypedText];
|
||||
- (void)saveLastQuery
|
||||
{
|
||||
if (self.lastQuery != nil && self.inputLocale != nil)
|
||||
{
|
||||
SearchQuery * query = [[SearchQuery alloc] init:self.lastQuery
|
||||
locale:self.inputLocale
|
||||
source:SearchTextSourceTypedText];
|
||||
[MWMSearch saveQuery:query];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - MWMSearchObserver
|
||||
|
||||
- (void)onSearchCompleted {
|
||||
- (void)onSearchCompleted
|
||||
{
|
||||
void (^completionHandler)(NSArray<MWMCarPlaySearchResultObject *> * searchResults) = self.completionHandler;
|
||||
if (completionHandler == nil) { return; }
|
||||
if (completionHandler == nil)
|
||||
return;
|
||||
|
||||
NSMutableArray<MWMCarPlaySearchResultObject *> * results = [NSMutableArray array];
|
||||
NSInteger count = [MWMSearch resultsCount];
|
||||
for (NSInteger row = 0; row < count; row++) {
|
||||
for (NSInteger row = 0; row < count; row++)
|
||||
{
|
||||
MWMCarPlaySearchResultObject * result = [[MWMCarPlaySearchResultObject alloc] initForRow:row];
|
||||
if (result != nil) { [results addObject:result]; }
|
||||
if (result != nil)
|
||||
[results addObject:result];
|
||||
}
|
||||
|
||||
self.lastResults = results;
|
||||
|
||||
@@ -40,10 +40,7 @@
|
||||
f.EnableChoosePositionMode(true /* enable */, enableBounds, optionalPosition);
|
||||
f.BlockTapEvents(true);
|
||||
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^
|
||||
{
|
||||
self.topConstraint.constant = 0;
|
||||
}];
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^{ self.topConstraint.constant = 0; }];
|
||||
}
|
||||
|
||||
- (void)dismissWithBlock:(MWMVoidBlock)block
|
||||
@@ -52,12 +49,9 @@
|
||||
f.EnableChoosePositionMode(false /* enable */, false /* enableBounds */, nullptr /* optionalPosition */);
|
||||
f.BlockTapEvents(false);
|
||||
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^
|
||||
{
|
||||
self.topConstraint.constant = -self.height;
|
||||
}
|
||||
completion:^(BOOL finished)
|
||||
{
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{ self.topConstraint.constant = -self.height; }
|
||||
completion:^(BOOL finished) {
|
||||
[self removeFromSuperview];
|
||||
block();
|
||||
}];
|
||||
|
||||
@@ -16,14 +16,16 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
|
||||
@implementation MWMAlertViewController
|
||||
|
||||
+ (nonnull MWMAlertViewController *)activeAlertController {
|
||||
+ (nonnull MWMAlertViewController *)activeAlertController
|
||||
{
|
||||
UIViewController * tvc = [MapViewController sharedController];
|
||||
ASSERT([tvc conformsToProtocol:@protocol(MWMController)], ());
|
||||
UIViewController<MWMController> * mwmController = static_cast<UIViewController<MWMController> *>(tvc);
|
||||
return mwmController.alertController;
|
||||
}
|
||||
|
||||
- (nonnull instancetype)initWithViewController:(nonnull UIViewController *)viewController {
|
||||
- (nonnull instancetype)initWithViewController:(nonnull UIViewController *)viewController
|
||||
{
|
||||
self = [super initWithNibName:kAlertControllerNibIdentifier bundle:nil];
|
||||
if (self)
|
||||
_ownerViewController = viewController;
|
||||
@@ -31,7 +33,8 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
||||
{
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
auto const orient = size.width > size.height ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait;
|
||||
[coordinator
|
||||
@@ -39,45 +42,54 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
for (MWMAlert * alert in self.view.subviews)
|
||||
[alert rotate:orient duration:context.transitionDuration];
|
||||
}
|
||||
completion:^(id<UIViewControllerTransitionCoordinatorContext> context){
|
||||
}];
|
||||
completion:^(id<UIViewControllerTransitionCoordinatorContext> context){}];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)presentLocationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
- (void)presentLocationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert locationAlertWithCancelBlock:cancelBlock]];
|
||||
}
|
||||
- (void)presentPoint2PointAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock needToRebuild:(BOOL)needToRebuild {
|
||||
- (void)presentPoint2PointAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock needToRebuild:(BOOL)needToRebuild
|
||||
{
|
||||
[self displayAlert:[MWMAlert point2PointAlertWithOkBlock:okBlock needToRebuild:needToRebuild]];
|
||||
}
|
||||
|
||||
- (void)presentLocationServiceNotSupportedAlert {
|
||||
- (void)presentLocationServiceNotSupportedAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert locationServiceNotSupportedAlert]];
|
||||
}
|
||||
- (void)presentNoConnectionAlert {
|
||||
- (void)presentNoConnectionAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert noConnectionAlert]];
|
||||
}
|
||||
|
||||
- (void)presentDeleteMapProhibitedAlert {
|
||||
- (void)presentDeleteMapProhibitedAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert deleteMapProhibitedAlert]];
|
||||
}
|
||||
- (void)presentUnsavedEditsAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock {
|
||||
- (void)presentUnsavedEditsAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert unsavedEditsAlertWithOkBlock:okBlock]];
|
||||
}
|
||||
|
||||
- (void)presentNoWiFiAlertWithOkBlock:(nullable MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
- (void)presentNoWiFiAlertWithOkBlock:(nullable MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert noWiFiAlertWithOkBlock:okBlock andCancelBlock:cancelBlock]];
|
||||
}
|
||||
|
||||
- (void)presentIncorrectFeauturePositionAlert {
|
||||
- (void)presentIncorrectFeauturePositionAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert incorrectFeaturePositionAlert]];
|
||||
}
|
||||
|
||||
- (void)presentNotEnoughSpaceAlert {
|
||||
- (void)presentNotEnoughSpaceAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert notEnoughSpaceAlert]];
|
||||
}
|
||||
- (void)presentInvalidUserNameOrPasswordAlert {
|
||||
- (void)presentInvalidUserNameOrPasswordAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert invalidUserNameOrPasswordAlert]];
|
||||
}
|
||||
|
||||
@@ -85,7 +97,8 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
code:(routing::RouterResultCode)code
|
||||
cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
downloadBlock:(MWMDownloadBlock)downloadBlock
|
||||
downloadCompleteBlock:(MWMVoidBlock)downloadCompleteBlock {
|
||||
downloadCompleteBlock:(MWMVoidBlock)downloadCompleteBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert downloaderAlertWithAbsentCountries:countries
|
||||
code:code
|
||||
cancelBlock:cancelBlock
|
||||
@@ -93,95 +106,113 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
downloadCompleteBlock:downloadCompleteBlock]];
|
||||
}
|
||||
|
||||
- (void)presentRoutingDisclaimerAlertWithOkBlock:(MWMVoidBlock)block {
|
||||
- (void)presentRoutingDisclaimerAlertWithOkBlock:(MWMVoidBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMAlert routingDisclaimerAlertWithOkBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentDisabledLocationAlert {
|
||||
- (void)presentDisabledLocationAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert disabledLocationAlert]];
|
||||
}
|
||||
|
||||
- (void)presentLocationServicesDisabledAlert; {
|
||||
- (void)presentLocationServicesDisabledAlert;
|
||||
{
|
||||
[self displayAlert:[MWMAlert locationServicesDisabledAlert]];
|
||||
}
|
||||
|
||||
- (void)presentAlert:(routing::RouterResultCode)type {
|
||||
- (void)presentAlert:(routing::RouterResultCode)type
|
||||
{
|
||||
[self displayAlert:[MWMAlert alert:type]];
|
||||
}
|
||||
|
||||
- (void)presentDownloaderNoConnectionAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock
|
||||
cancelBlock:(nonnull MWMVoidBlock)cancelBlock {
|
||||
cancelBlock:(nonnull MWMVoidBlock)cancelBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert downloaderNoConnectionAlertWithOkBlock:okBlock cancelBlock:cancelBlock]];
|
||||
}
|
||||
|
||||
- (void)presentDownloaderNotEnoughSpaceAlert {
|
||||
- (void)presentDownloaderNotEnoughSpaceAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert downloaderNotEnoughSpaceAlert]];
|
||||
}
|
||||
|
||||
- (void)presentDownloaderInternalErrorAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock
|
||||
cancelBlock:(nonnull MWMVoidBlock)cancelBlock {
|
||||
cancelBlock:(nonnull MWMVoidBlock)cancelBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert downloaderInternalErrorAlertWithOkBlock:okBlock cancelBlock:cancelBlock]];
|
||||
}
|
||||
|
||||
- (void)presentPlaceDoesntExistAlertWithBlock:(MWMStringBlock)block {
|
||||
- (void)presentPlaceDoesntExistAlertWithBlock:(MWMStringBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMAlert placeDoesntExistAlertWithBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentResetChangesAlertWithBlock:(MWMVoidBlock)block {
|
||||
- (void)presentResetChangesAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMAlert resetChangesAlertWithBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentDeleteFeatureAlertWithBlock:(MWMVoidBlock)block {
|
||||
- (void)presentDeleteFeatureAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMAlert deleteFeatureAlertWithBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentPersonalInfoWarningAlertWithBlock:(nonnull MWMVoidBlock)block {
|
||||
- (void)presentPersonalInfoWarningAlertWithBlock:(nonnull MWMVoidBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMAlert personalInfoWarningAlertWithBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentTrackWarningAlertWithCancelBlock:(nonnull MWMVoidBlock)block {
|
||||
- (void)presentTrackWarningAlertWithCancelBlock:(nonnull MWMVoidBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMAlert trackWarningAlertWithCancelBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentMobileInternetAlertWithBlock:(nonnull MWMMobileInternetAlertCompletionBlock)block {
|
||||
- (void)presentMobileInternetAlertWithBlock:(nonnull MWMMobileInternetAlertCompletionBlock)block
|
||||
{
|
||||
[self displayAlert:[MWMMobileInternetAlert alertWithBlock:block]];
|
||||
}
|
||||
|
||||
- (void)presentInfoAlert:(nonnull NSString *)title text:(nonnull NSString *)text {
|
||||
- (void)presentInfoAlert:(nonnull NSString *)title text:(nonnull NSString *)text
|
||||
{
|
||||
[self displayAlert:[MWMAlert infoAlert:title text:text]];
|
||||
}
|
||||
|
||||
- (void)presentInfoAlert:(nonnull NSString *)title {
|
||||
- (void)presentInfoAlert:(nonnull NSString *)title
|
||||
{
|
||||
[self displayAlert:[MWMAlert infoAlert:title text:nil]];
|
||||
}
|
||||
|
||||
- (void)presentCreateBookmarkCategoryAlertWithMaxCharacterNum:(NSUInteger)max
|
||||
minCharacterNum:(NSUInteger)min
|
||||
callback:(nonnull MWMCheckStringBlock)callback {
|
||||
callback:(nonnull MWMCheckStringBlock)callback
|
||||
{
|
||||
auto alert =
|
||||
static_cast<MWMBCCreateCategoryAlert *>([MWMAlert createBookmarkCategoryAlertWithMaxCharacterNum:max
|
||||
minCharacterNum:min
|
||||
callback:callback]);
|
||||
[self displayAlert:alert];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[alert.textField becomeFirstResponder];
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [alert.textField becomeFirstResponder]; });
|
||||
}
|
||||
|
||||
- (void)presentSpinnerAlertWithTitle:(nonnull NSString *)title cancel:(nullable MWMVoidBlock)cancel {
|
||||
- (void)presentSpinnerAlertWithTitle:(nonnull NSString *)title cancel:(nullable MWMVoidBlock)cancel
|
||||
{
|
||||
[self displayAlert:[MWMAlert spinnerAlertWithTitle:title cancel:cancel]];
|
||||
}
|
||||
|
||||
- (void)presentBookmarkConversionErrorAlert {
|
||||
- (void)presentBookmarkConversionErrorAlert
|
||||
{
|
||||
[self displayAlert:[MWMAlert bookmarkConversionErrorAlert]];
|
||||
}
|
||||
|
||||
- (void)presentTagsLoadingErrorAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock
|
||||
cancelBlock:(nonnull MWMVoidBlock)cancelBlock {
|
||||
cancelBlock:(nonnull MWMVoidBlock)cancelBlock
|
||||
{
|
||||
[self displayAlert:[MWMAlert tagsLoadingErrorAlertWithOkBlock:okBlock cancelBlock:cancelBlock]];
|
||||
}
|
||||
|
||||
- (void)presentBugReportAlertWithTitle:(nonnull NSString *)title {
|
||||
- (void)presentBugReportAlertWithTitle:(nonnull NSString *)title
|
||||
{
|
||||
[self displayAlert:[MWMAlert bugReportAlertWithTitle:title]];
|
||||
}
|
||||
|
||||
@@ -189,7 +220,8 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
message:(nullable NSString *)message
|
||||
rightButtonTitle:(nonnull NSString *)rightButtonTitle
|
||||
leftButtonTitle:(nullable NSString *)leftButtonTitle
|
||||
rightButtonAction:(nullable MWMVoidBlock)action {
|
||||
rightButtonAction:(nullable MWMVoidBlock)action
|
||||
{
|
||||
[self displayAlert:[MWMAlert defaultAlertWithTitle:title
|
||||
message:message
|
||||
rightButtonTitle:rightButtonTitle
|
||||
@@ -197,33 +229,31 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
rightButtonAction:action]];
|
||||
}
|
||||
|
||||
- (void)displayAlert:(MWMAlert *)alert {
|
||||
- (void)displayAlert:(MWMAlert *)alert
|
||||
{
|
||||
UIViewController * ownerVC = self.ownerViewController;
|
||||
if (ownerVC.navigationController != nil) {
|
||||
if (ownerVC.navigationController != nil)
|
||||
ownerVC = ownerVC.navigationController;
|
||||
}
|
||||
BOOL isOwnerLoaded = ownerVC.isViewLoaded;
|
||||
if (!isOwnerLoaded) {
|
||||
if (!isOwnerLoaded)
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(igrechuhin): Remove this check on location manager refactoring.
|
||||
// Workaround for current location manager duplicate error alerts.
|
||||
if ([alert isKindOfClass:[MWMLocationAlert class]]) {
|
||||
for (MWMAlert *view in self.view.subviews) {
|
||||
if ([alert isKindOfClass:[MWMLocationAlert class]])
|
||||
{
|
||||
for (MWMAlert * view in self.view.subviews)
|
||||
if ([view isKindOfClass:[MWMLocationAlert class]])
|
||||
return;
|
||||
}
|
||||
}
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
delay:0
|
||||
options:UIViewAnimationOptionBeginFromCurrentState
|
||||
animations:^{
|
||||
for (MWMAlert *view in self.view.subviews) {
|
||||
for (MWMAlert * view in self.view.subviews)
|
||||
if (view != alert)
|
||||
view.alpha = 0.0;
|
||||
}
|
||||
}
|
||||
completion:nil];
|
||||
|
||||
[self willMoveToParentViewController:NULL];
|
||||
@@ -250,7 +280,8 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
[[MapsAppDelegate theApp].window endEditing:YES];
|
||||
}
|
||||
|
||||
- (void)closeAlert:(nullable MWMVoidBlock)completion {
|
||||
- (void)closeAlert:(nullable MWMVoidBlock)completion
|
||||
{
|
||||
NSArray * subviews = self.view.subviews;
|
||||
MWMAlert * closeAlert = subviews.lastObject;
|
||||
MWMAlert * showAlert = (subviews.count >= 2 ? subviews[subviews.count - 2] : nil);
|
||||
@@ -266,7 +297,8 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController"
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[closeAlert removeFromSuperview];
|
||||
if (!showAlert) {
|
||||
if (!showAlert)
|
||||
{
|
||||
[self.view removeFromSuperview];
|
||||
[self removeFromParentViewController];
|
||||
}
|
||||
|
||||
@@ -10,42 +10,52 @@
|
||||
|
||||
@implementation MWMAlert
|
||||
|
||||
+ (MWMAlert *)locationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (MWMAlert *)locationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
return [MWMLocationAlert alertWithCancelBlock:cancelBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)point2PointAlertWithOkBlock:(MWMVoidBlock)block needToRebuild:(BOOL)needToRebuild {
|
||||
+ (MWMAlert *)point2PointAlertWithOkBlock:(MWMVoidBlock)block needToRebuild:(BOOL)needToRebuild
|
||||
{
|
||||
return [MWMDefaultAlert point2PointAlertWithOkBlock:block needToRebuild:needToRebuild];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)routingDisclaimerAlertWithOkBlock:(MWMVoidBlock)block {
|
||||
+ (MWMAlert *)routingDisclaimerAlertWithOkBlock:(MWMVoidBlock)block
|
||||
{
|
||||
return [MWMRoutingDisclaimerAlert alertWithOkBlock:block];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)disabledLocationAlert {
|
||||
+ (MWMAlert *)disabledLocationAlert
|
||||
{
|
||||
return [MWMDefaultAlert disabledLocationAlert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)locationServicesDisabledAlert {
|
||||
+ (MWMAlert *)locationServicesDisabledAlert
|
||||
{
|
||||
return [LocationServicesDisabledAlert alert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)noWiFiAlertWithOkBlock:(MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (MWMAlert *)noWiFiAlertWithOkBlock:(MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
return [MWMDefaultAlert noWiFiAlertWithOkBlock:okBlock andCancelBlock:cancelBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)noConnectionAlert {
|
||||
+ (MWMAlert *)noConnectionAlert
|
||||
{
|
||||
return [MWMDefaultAlert noConnectionAlert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)deleteMapProhibitedAlert {
|
||||
+ (MWMAlert *)deleteMapProhibitedAlert
|
||||
{
|
||||
return [MWMDefaultAlert deleteMapProhibitedAlert];
|
||||
}
|
||||
+ (MWMAlert *)unsavedEditsAlertWithOkBlock:(MWMVoidBlock)okBlock {
|
||||
+ (MWMAlert *)unsavedEditsAlertWithOkBlock:(MWMVoidBlock)okBlock
|
||||
{
|
||||
return [MWMDefaultAlert unsavedEditsAlertWithOkBlock:okBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)locationServiceNotSupportedAlert {
|
||||
+ (MWMAlert *)locationServiceNotSupportedAlert
|
||||
{
|
||||
return [MWMDefaultAlert locationServiceNotSupportedAlert];
|
||||
}
|
||||
|
||||
@@ -53,7 +63,8 @@
|
||||
code:(routing::RouterResultCode)code
|
||||
cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
downloadBlock:(MWMDownloadBlock)downloadBlock
|
||||
downloadCompleteBlock:(MWMVoidBlock)downloadCompleteBlock {
|
||||
downloadCompleteBlock:(MWMVoidBlock)downloadCompleteBlock
|
||||
{
|
||||
return [MWMDownloadTransitMapAlert downloaderAlertWithMaps:countries
|
||||
code:code
|
||||
cancelBlock:cancelBlock
|
||||
@@ -61,105 +72,115 @@
|
||||
downloadCompleteBlock:downloadCompleteBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)alert:(routing::RouterResultCode)type {
|
||||
switch (type) {
|
||||
case routing::RouterResultCode::NoCurrentPosition:
|
||||
return [MWMDefaultAlert noCurrentPositionAlert];
|
||||
case routing::RouterResultCode::StartPointNotFound:
|
||||
return [MWMDefaultAlert startPointNotFoundAlert];
|
||||
case routing::RouterResultCode::EndPointNotFound:
|
||||
return [MWMDefaultAlert endPointNotFoundAlert];
|
||||
case routing::RouterResultCode::PointsInDifferentMWM:
|
||||
return [MWMDefaultAlert pointsInDifferentMWMAlert];
|
||||
+ (MWMAlert *)alert:(routing::RouterResultCode)type
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case routing::RouterResultCode::NoCurrentPosition: return [MWMDefaultAlert noCurrentPositionAlert];
|
||||
case routing::RouterResultCode::StartPointNotFound: return [MWMDefaultAlert startPointNotFoundAlert];
|
||||
case routing::RouterResultCode::EndPointNotFound: return [MWMDefaultAlert endPointNotFoundAlert];
|
||||
case routing::RouterResultCode::PointsInDifferentMWM: return [MWMDefaultAlert pointsInDifferentMWMAlert];
|
||||
case routing::RouterResultCode::TransitRouteNotFoundNoNetwork:
|
||||
return [MWMDefaultAlert routeNotFoundNoPublicTransportAlert];
|
||||
case routing::RouterResultCode::TransitRouteNotFoundTooLongPedestrian:
|
||||
return [MWMDefaultAlert routeNotFoundTooLongPedestrianAlert];
|
||||
case routing::RouterResultCode::RouteNotFoundRedressRouteError:
|
||||
case routing::RouterResultCode::RouteNotFound:
|
||||
case routing::RouterResultCode::InconsistentMWMandRoute:
|
||||
return [MWMDefaultAlert routeNotFoundAlert];
|
||||
case routing::RouterResultCode::InconsistentMWMandRoute: return [MWMDefaultAlert routeNotFoundAlert];
|
||||
case routing::RouterResultCode::RouteFileNotExist:
|
||||
case routing::RouterResultCode::FileTooOld:
|
||||
return [MWMDefaultAlert routeFileNotExistAlert];
|
||||
case routing::RouterResultCode::InternalError:
|
||||
return [MWMDefaultAlert internalRoutingErrorAlert];
|
||||
case routing::RouterResultCode::FileTooOld: return [MWMDefaultAlert routeFileNotExistAlert];
|
||||
case routing::RouterResultCode::InternalError: return [MWMDefaultAlert internalRoutingErrorAlert];
|
||||
case routing::RouterResultCode::Cancelled:
|
||||
case routing::RouterResultCode::NoError:
|
||||
case routing::RouterResultCode::HasWarnings:
|
||||
case routing::RouterResultCode::NeedMoreMaps:
|
||||
return nil;
|
||||
case routing::RouterResultCode::IntermediatePointNotFound:
|
||||
return [MWMDefaultAlert intermediatePointNotFoundAlert];
|
||||
case routing::RouterResultCode::NeedMoreMaps: return nil;
|
||||
case routing::RouterResultCode::IntermediatePointNotFound: return [MWMDefaultAlert intermediatePointNotFoundAlert];
|
||||
}
|
||||
}
|
||||
|
||||
+ (MWMAlert *)incorrectFeaturePositionAlert {
|
||||
+ (MWMAlert *)incorrectFeaturePositionAlert
|
||||
{
|
||||
return [MWMDefaultAlert incorrectFeaturePositionAlert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)notEnoughSpaceAlert {
|
||||
+ (MWMAlert *)notEnoughSpaceAlert
|
||||
{
|
||||
return [MWMDefaultAlert notEnoughSpaceAlert];
|
||||
}
|
||||
+ (MWMAlert *)invalidUserNameOrPasswordAlert {
|
||||
+ (MWMAlert *)invalidUserNameOrPasswordAlert
|
||||
{
|
||||
return [MWMDefaultAlert invalidUserNameOrPasswordAlert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)downloaderNoConnectionAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (MWMAlert *)downloaderNoConnectionAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
return [MWMDefaultAlert downloaderNoConnectionAlertWithOkBlock:okBlock cancelBlock:cancelBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)downloaderNotEnoughSpaceAlert {
|
||||
+ (MWMAlert *)downloaderNotEnoughSpaceAlert
|
||||
{
|
||||
return [MWMDefaultAlert downloaderNotEnoughSpaceAlert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)downloaderInternalErrorAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (MWMAlert *)downloaderInternalErrorAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
return [MWMDefaultAlert downloaderInternalErrorAlertWithOkBlock:okBlock cancelBlock:cancelBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)placeDoesntExistAlertWithBlock:(MWMStringBlock)block {
|
||||
+ (MWMAlert *)placeDoesntExistAlertWithBlock:(MWMStringBlock)block
|
||||
{
|
||||
return [MWMPlaceDoesntExistAlert alertWithBlock:block];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)resetChangesAlertWithBlock:(MWMVoidBlock)block {
|
||||
+ (MWMAlert *)resetChangesAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
return [MWMDefaultAlert resetChangesAlertWithBlock:block];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)deleteFeatureAlertWithBlock:(MWMVoidBlock)block {
|
||||
+ (MWMAlert *)deleteFeatureAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
return [MWMDefaultAlert deleteFeatureAlertWithBlock:block];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)personalInfoWarningAlertWithBlock:(MWMVoidBlock)block {
|
||||
+ (MWMAlert *)personalInfoWarningAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
return [MWMDefaultAlert personalInfoWarningAlertWithBlock:block];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)trackWarningAlertWithCancelBlock:(MWMVoidBlock)block {
|
||||
+ (MWMAlert *)trackWarningAlertWithCancelBlock:(MWMVoidBlock)block
|
||||
{
|
||||
return [MWMDefaultAlert trackWarningAlertWithCancelBlock:block];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)infoAlert:(NSString *)title text:(NSString *)text {
|
||||
+ (MWMAlert *)infoAlert:(NSString *)title text:(NSString *)text
|
||||
{
|
||||
return [MWMDefaultAlert infoAlert:title text:text];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)createBookmarkCategoryAlertWithMaxCharacterNum:(NSUInteger)max
|
||||
minCharacterNum:(NSUInteger)min
|
||||
callback:(MWMCheckStringBlock)callback {
|
||||
callback:(MWMCheckStringBlock)callback
|
||||
{
|
||||
return [MWMBCCreateCategoryAlert alertWithMaxCharachersNum:max minCharactersNum:min callback:callback];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)spinnerAlertWithTitle:(NSString *)title cancel:(MWMVoidBlock)cancel {
|
||||
+ (MWMAlert *)spinnerAlertWithTitle:(NSString *)title cancel:(MWMVoidBlock)cancel
|
||||
{
|
||||
return [MWMSpinnerAlert alertWithTitle:title cancel:cancel];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)bookmarkConversionErrorAlert {
|
||||
+ (MWMAlert *)bookmarkConversionErrorAlert
|
||||
{
|
||||
return [MWMDefaultAlert bookmarkConversionErrorAlert];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)tagsLoadingErrorAlertWithOkBlock:okBlock cancelBlock:cancelBlock {
|
||||
+ (MWMAlert *)tagsLoadingErrorAlertWithOkBlock:okBlock cancelBlock:cancelBlock
|
||||
{
|
||||
return [MWMDefaultAlert tagsLoadingErrorAlertWithOkBlock:okBlock cancelBlock:cancelBlock];
|
||||
}
|
||||
|
||||
+ (MWMAlert *)bugReportAlertWithTitle:(NSString *)title {
|
||||
+ (MWMAlert *)bugReportAlertWithTitle:(NSString *)title
|
||||
{
|
||||
return [MWMDefaultAlert bugReportAlertWithTitle:title];
|
||||
}
|
||||
|
||||
@@ -167,7 +188,8 @@
|
||||
message:(NSString *)message
|
||||
rightButtonTitle:(NSString *)rightButtonTitle
|
||||
leftButtonTitle:(NSString *)leftButtonTitle
|
||||
rightButtonAction:(MWMVoidBlock)action {
|
||||
rightButtonAction:(MWMVoidBlock)action
|
||||
{
|
||||
return [MWMDefaultAlert defaultAlertWithTitle:title
|
||||
message:message
|
||||
rightButtonTitle:rightButtonTitle
|
||||
@@ -176,54 +198,63 @@
|
||||
log:nil];
|
||||
}
|
||||
|
||||
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
|
||||
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
|
||||
{
|
||||
// Should override this method if you want custom relayout after rotation.
|
||||
}
|
||||
|
||||
- (void)close:(MWMVoidBlock)completion {
|
||||
- (void)close:(MWMVoidBlock)completion
|
||||
{
|
||||
[self.alertController closeAlert:completion];
|
||||
}
|
||||
- (void)setNeedsCloseAlertAfterEnterBackground {
|
||||
- (void)setNeedsCloseAlertAfterEnterBackground
|
||||
{
|
||||
[NSNotificationCenter.defaultCenter addObserver:self
|
||||
selector:@selector(applicationDidEnterBackground)
|
||||
name:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
- (void)dealloc
|
||||
{
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self];
|
||||
}
|
||||
- (void)applicationDidEnterBackground {
|
||||
- (void)applicationDidEnterBackground
|
||||
{
|
||||
// Should close alert when application entered background.
|
||||
[self close:nil];
|
||||
}
|
||||
|
||||
- (void)rotate:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
|
||||
- (void)rotate:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
|
||||
{
|
||||
if ([self respondsToSelector:@selector(willRotateToInterfaceOrientation:)])
|
||||
[self willRotateToInterfaceOrientation:toInterfaceOrientation];
|
||||
}
|
||||
|
||||
- (void)addControllerViewToWindow {
|
||||
- (void)addControllerViewToWindow
|
||||
{
|
||||
UIWindow * window = UIApplication.sharedApplication.delegate.window;
|
||||
UIView * view = self.alertController.view;
|
||||
[window addSubview:view];
|
||||
view.frame = window.bounds;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
self.frame = self.superview.bounds;
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
if (self.traitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle) {
|
||||
if (self.traitCollection.userInterfaceStyle != previousTraitCollection.userInterfaceStyle)
|
||||
[self updateViewStyle:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateViewStyle:(UIView *)view {
|
||||
- (void)updateViewStyle:(UIView *)view
|
||||
{
|
||||
if (!view)
|
||||
return;
|
||||
for (UIView * subview in view.subviews)
|
||||
|
||||
@@ -23,7 +23,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
|
||||
@implementation MWMDefaultAlert
|
||||
|
||||
+ (instancetype)routeFileNotExistAlert {
|
||||
+ (instancetype)routeFileNotExistAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_download_files")
|
||||
message:L(@"dialog_routing_download_and_update_all")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -32,7 +33,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Route File Not Exist Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)routeNotFoundAlert {
|
||||
+ (instancetype)routeNotFoundAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_unable_locate_route")
|
||||
message:L(@"dialog_routing_change_start_or_end")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -41,7 +43,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Route File Not Exist Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)routeNotFoundNoPublicTransportAlert {
|
||||
+ (instancetype)routeNotFoundNoPublicTransportAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"transit_not_found")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -50,7 +53,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"transit_not_found"];
|
||||
}
|
||||
|
||||
+ (instancetype)routeNotFoundTooLongPedestrianAlert {
|
||||
+ (instancetype)routeNotFoundTooLongPedestrianAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"dialog_pedestrian_route_is_long_header")
|
||||
message:L(@"dialog_pedestrian_route_is_long_message")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -59,7 +63,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Long Pedestrian Route Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)locationServiceNotSupportedAlert {
|
||||
+ (instancetype)locationServiceNotSupportedAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"current_location_unknown_error_title")
|
||||
message:L(@"current_location_unknown_error_message")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -68,7 +73,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Location Service Not Supported Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)noConnectionAlert {
|
||||
+ (instancetype)noConnectionAlert
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"common_check_internet_connection_dialog")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -79,7 +85,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)deleteMapProhibitedAlert {
|
||||
+ (instancetype)deleteMapProhibitedAlert
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"downloader_delete_map")
|
||||
message:L(@"downloader_delete_map_while_routing_dialog")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -90,7 +97,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)unsavedEditsAlertWithOkBlock:(MWMVoidBlock)okBlock {
|
||||
+ (instancetype)unsavedEditsAlertWithOkBlock:(MWMVoidBlock)okBlock
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"please_note")
|
||||
message:L(@"downloader_delete_map_dialog")
|
||||
rightButtonTitle:L(@"delete")
|
||||
@@ -99,7 +107,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Editor unsaved changes on delete"];
|
||||
}
|
||||
|
||||
+ (instancetype)noWiFiAlertWithOkBlock:(MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (instancetype)noWiFiAlertWithOkBlock:(MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"download_over_mobile_header")
|
||||
message:L(@"download_over_mobile_message")
|
||||
rightButtonTitle:L(@"use_cellular_data")
|
||||
@@ -111,7 +120,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)endPointNotFoundAlert {
|
||||
+ (instancetype)endPointNotFoundAlert
|
||||
{
|
||||
NSString * message = [NSString
|
||||
stringWithFormat:@"%@\n\n%@", L(@"dialog_routing_end_not_determined"), L(@"dialog_routing_select_closer_end")];
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_change_end")
|
||||
@@ -122,9 +132,10 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"End Point Not Found Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)startPointNotFoundAlert {
|
||||
NSString *message = [NSString
|
||||
stringWithFormat:@"%@\n\n%@", L(@"dialog_routing_start_not_determined"), L(@"dialog_routing_select_closer_start")];
|
||||
+ (instancetype)startPointNotFoundAlert
|
||||
{
|
||||
NSString * message = [NSString stringWithFormat:@"%@\n\n%@", L(@"dialog_routing_start_not_determined"),
|
||||
L(@"dialog_routing_select_closer_start")];
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_change_start")
|
||||
message:message
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -133,7 +144,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Start Point Not Found Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)intermediatePointNotFoundAlert {
|
||||
+ (instancetype)intermediatePointNotFoundAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_change_intermediate")
|
||||
message:L(@"dialog_routing_intermediate_not_determined")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -142,7 +154,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Intermediate Point Not Found Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)internalRoutingErrorAlert {
|
||||
+ (instancetype)internalRoutingErrorAlert
|
||||
{
|
||||
NSString * message =
|
||||
[NSString stringWithFormat:@"%@\n\n%@", L(@"dialog_routing_application_error"), L(@"dialog_routing_try_again")];
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_system_error")
|
||||
@@ -153,7 +166,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Internal Routing Error Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)incorrectFeaturePositionAlert {
|
||||
+ (instancetype)incorrectFeaturePositionAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"dialog_incorrect_feature_position")
|
||||
message:L(@"message_invalid_feature_position")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -162,7 +176,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Incorrect Feature Possition Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)notEnoughSpaceAlert {
|
||||
+ (instancetype)notEnoughSpaceAlert
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"downloader_no_space_title")
|
||||
message:L(@"migration_no_space_message")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -173,7 +188,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)invalidUserNameOrPasswordAlert {
|
||||
+ (instancetype)invalidUserNameOrPasswordAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"invalid_username_or_password")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -182,7 +198,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Invalid User Name or Password Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)noCurrentPositionAlert {
|
||||
+ (instancetype)noCurrentPositionAlert
|
||||
{
|
||||
NSString * message = [NSString stringWithFormat:@"%@\n\n%@", L(@"dialog_routing_error_location_not_found"),
|
||||
L(@"dialog_routing_location_turn_wifi")];
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_check_gps")
|
||||
@@ -193,10 +210,9 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"No Current Position Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)disabledLocationAlert {
|
||||
MWMVoidBlock action = ^{
|
||||
GetFramework().SwitchMyPositionNextMode();
|
||||
};
|
||||
+ (instancetype)disabledLocationAlert
|
||||
{
|
||||
MWMVoidBlock action = ^{ GetFramework().SwitchMyPositionNextMode(); };
|
||||
return [self defaultAlertWithTitle:L(@"dialog_routing_location_turn_on")
|
||||
message:L(@"dialog_routing_location_unknown_turn_on")
|
||||
rightButtonTitle:L(@"turn_on")
|
||||
@@ -205,7 +221,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Disabled Location Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)pointsInDifferentMWMAlert {
|
||||
+ (instancetype)pointsInDifferentMWMAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"routing_failed_cross_mwm_building")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -214,15 +231,19 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Points In Different MWM Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)point2PointAlertWithOkBlock:(MWMVoidBlock)okBlock needToRebuild:(BOOL)needToRebuild {
|
||||
if (needToRebuild) {
|
||||
+ (instancetype)point2PointAlertWithOkBlock:(MWMVoidBlock)okBlock needToRebuild:(BOOL)needToRebuild
|
||||
{
|
||||
if (needToRebuild)
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"p2p_only_from_current")
|
||||
message:L(@"p2p_reroute_from_current")
|
||||
rightButtonTitle:L(@"ok")
|
||||
leftButtonTitle:L(@"cancel")
|
||||
rightButtonAction:okBlock
|
||||
log:@"Default Alert"];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"p2p_only_from_current")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -232,7 +253,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
}
|
||||
}
|
||||
|
||||
+ (instancetype)downloaderNoConnectionAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (instancetype)downloaderNoConnectionAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"downloader_status_failed")
|
||||
message:L(@"common_check_internet_connection_dialog")
|
||||
rightButtonTitle:L(@"downloader_retry")
|
||||
@@ -244,7 +266,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)downloaderNotEnoughSpaceAlert {
|
||||
+ (instancetype)downloaderNotEnoughSpaceAlert
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"downloader_no_space_title")
|
||||
message:L(@"downloader_no_space_message")
|
||||
rightButtonTitle:L(@"close")
|
||||
@@ -255,7 +278,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)downloaderInternalErrorAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (instancetype)downloaderInternalErrorAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"migration_download_error_dialog")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"downloader_retry")
|
||||
@@ -267,7 +291,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)resetChangesAlertWithBlock:(MWMVoidBlock)block {
|
||||
+ (instancetype)resetChangesAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"editor_reset_edits_message")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"editor_reset_edits_button")
|
||||
@@ -277,7 +302,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)deleteFeatureAlertWithBlock:(MWMVoidBlock)block {
|
||||
+ (instancetype)deleteFeatureAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"editor_remove_place_message")
|
||||
message:nil
|
||||
rightButtonTitle:L(@"editor_remove_place_button")
|
||||
@@ -287,9 +313,10 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)personalInfoWarningAlertWithBlock:(MWMVoidBlock)block {
|
||||
NSString *message = [NSString
|
||||
stringWithFormat:@"%@\n%@", L(@"editor_share_to_all_dialog_message_1"), L(@"editor_share_to_all_dialog_message_2")];
|
||||
+ (instancetype)personalInfoWarningAlertWithBlock:(MWMVoidBlock)block
|
||||
{
|
||||
NSString * message = [NSString stringWithFormat:@"%@\n%@", L(@"editor_share_to_all_dialog_message_1"),
|
||||
L(@"editor_share_to_all_dialog_message_2")];
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"editor_share_to_all_dialog_title")
|
||||
message:message
|
||||
rightButtonTitle:L(@"editor_report_problem_send_button")
|
||||
@@ -299,7 +326,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)trackWarningAlertWithCancelBlock:(MWMVoidBlock)block {
|
||||
+ (instancetype)trackWarningAlertWithCancelBlock:(MWMVoidBlock)block
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"recent_track_background_dialog_title")
|
||||
message:L(@"recent_track_background_dialog_message")
|
||||
rightButtonTitle:L(@"off_recent_track_background_button")
|
||||
@@ -309,7 +337,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)infoAlert:(NSString *)title text:(NSString *)text {
|
||||
+ (instancetype)infoAlert:(NSString *)title text:(NSString *)text
|
||||
{
|
||||
return [self defaultAlertWithTitle:title
|
||||
message:text
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -318,7 +347,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:@"Info Alert"];
|
||||
}
|
||||
|
||||
+ (instancetype)convertBookmarksWithCount:(NSUInteger)count okBlock:(MWMVoidBlock)okBlock {
|
||||
+ (instancetype)convertBookmarksWithCount:(NSUInteger)count okBlock:(MWMVoidBlock)okBlock
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"bookmarks_detect_title")
|
||||
message:[NSString stringWithFormat:L(@"bookmarks_detect_message"), count]
|
||||
rightButtonTitle:L(@"button_convert")
|
||||
@@ -327,7 +357,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:nil];
|
||||
}
|
||||
|
||||
+ (instancetype)bookmarkConversionErrorAlert {
|
||||
+ (instancetype)bookmarkConversionErrorAlert
|
||||
{
|
||||
return [self defaultAlertWithTitle:L(@"bookmarks_convert_error_title")
|
||||
message:L(@"bookmarks_convert_error_message")
|
||||
rightButtonTitle:L(@"ok")
|
||||
@@ -336,7 +367,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
log:nil];
|
||||
}
|
||||
|
||||
+ (instancetype)tagsLoadingErrorAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock {
|
||||
+ (instancetype)tagsLoadingErrorAlertWithOkBlock:(MWMVoidBlock)okBlock cancelBlock:(MWMVoidBlock)cancelBlock
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:L(@"title_error_downloading_bookmarks")
|
||||
message:L(@"tags_loading_error_subtitle")
|
||||
rightButtonTitle:L(@"downloader_retry")
|
||||
@@ -348,7 +380,8 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
return alert;
|
||||
}
|
||||
|
||||
+ (instancetype)bugReportAlertWithTitle:(NSString *)title {
|
||||
+ (instancetype)bugReportAlertWithTitle:(NSString *)title
|
||||
{
|
||||
MWMDefaultAlert * alert = [self defaultAlertWithTitle:title
|
||||
message:L(@"bugreport_alert_message")
|
||||
rightButtonTitle:L(@"report_a_bug")
|
||||
@@ -364,14 +397,15 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
rightButtonTitle:(NSString *)rightButtonTitle
|
||||
leftButtonTitle:(NSString *)leftButtonTitle
|
||||
rightButtonAction:(MWMVoidBlock)action
|
||||
log:(NSString *)log {
|
||||
if (log) {
|
||||
log:(NSString *)log
|
||||
{
|
||||
if (log)
|
||||
LOG(LINFO, ([log UTF8String]));
|
||||
}
|
||||
MWMDefaultAlert * alert = [NSBundle.mainBundle loadNibNamed:kDefaultAlertNibName owner:self options:nil].firstObject;
|
||||
alert.titleLabel.text = title;
|
||||
alert.messageLabel.text = message;
|
||||
if (!message) {
|
||||
if (!message)
|
||||
{
|
||||
alert.dividerTop.constant = kDividerTopConstant;
|
||||
[alert layoutIfNeeded];
|
||||
}
|
||||
@@ -380,10 +414,13 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
[alert.rightButton setTitle:rightButtonTitle forState:UIControlStateDisabled];
|
||||
|
||||
alert.rightButtonAction = action;
|
||||
if (leftButtonTitle) {
|
||||
if (leftButtonTitle)
|
||||
{
|
||||
[alert.leftButton setTitle:leftButtonTitle forState:UIControlStateNormal];
|
||||
[alert.leftButton setTitle:leftButtonTitle forState:UIControlStateDisabled];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
alert.vDivider.hidden = YES;
|
||||
alert.leftButton.hidden = YES;
|
||||
alert.rightButtonWidth.constant = [alert.subviews.firstObject width];
|
||||
@@ -393,11 +430,13 @@ static NSString *const kDefaultAlertNibName = @"MWMDefaultAlert";
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)rightButtonTap {
|
||||
- (IBAction)rightButtonTap
|
||||
{
|
||||
[self close:self.rightButtonAction];
|
||||
}
|
||||
|
||||
- (IBAction)leftButtonTap {
|
||||
- (IBAction)leftButtonTap
|
||||
{
|
||||
[self close:self.leftButtonAction];
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ CGFloat const kMinimumOffset = 20.;
|
||||
CGFloat const kAnimationDuration = .05;
|
||||
} // namespace
|
||||
|
||||
@interface MWMDownloadTransitMapAlert () <UITableViewDataSource, UITableViewDelegate, MWMStorageObserver, MWMCircularProgressProtocol>
|
||||
@interface MWMDownloadTransitMapAlert () <UITableViewDataSource,
|
||||
UITableViewDelegate,
|
||||
MWMStorageObserver,
|
||||
MWMCircularProgressProtocol>
|
||||
|
||||
@property(copy, nonatomic) MWMVoidBlock cancelBlock;
|
||||
@property(copy, nonatomic) MWMDownloadBlock downloadBlock;
|
||||
@@ -76,9 +79,7 @@ CGFloat const kAnimationDuration = .05;
|
||||
alert.titleLabel.text = L(@"dialog_routing_download_and_build_cross_route");
|
||||
alert.messageLabel.text = L(@"dialog_routing_download_cross_route");
|
||||
break;
|
||||
default:
|
||||
NSAssert(false, @"Incorrect code!");
|
||||
break;
|
||||
default: NSAssert(false, @"Incorrect code!"); break;
|
||||
}
|
||||
alert.cancelBlock = cancelBlock;
|
||||
alert.downloadBlock = downloadBlock;
|
||||
@@ -90,8 +91,7 @@ CGFloat const kAnimationDuration = .05;
|
||||
{
|
||||
NSAssert(!countries.empty(), @"countries can not be empty.");
|
||||
MWMDownloadTransitMapAlert * alert =
|
||||
[NSBundle.mainBundle loadNibNamed:kDownloadTransitMapAlertNibName owner:nil options:nil]
|
||||
.firstObject;
|
||||
[NSBundle.mainBundle loadNibNamed:kDownloadTransitMapAlertNibName owner:nil options:nil].firstObject;
|
||||
|
||||
alert->m_countries = storage::CountriesVec(countries.begin(), countries.end());
|
||||
[alert configure];
|
||||
@@ -113,8 +113,7 @@ CGFloat const kAnimationDuration = .05;
|
||||
- (void)updateCountriesList
|
||||
{
|
||||
auto const & s = GetFramework().GetStorage();
|
||||
m_countries.erase(
|
||||
remove_if(m_countries.begin(), m_countries.end(),
|
||||
m_countries.erase(remove_if(m_countries.begin(), m_countries.end(),
|
||||
[&s](storage::CountryId const & countryId) { return s.HasLatestVersion(countryId); }),
|
||||
m_countries.end());
|
||||
NSMutableArray<NSString *> * titles = [@[] mutableCopy];
|
||||
@@ -170,16 +169,13 @@ CGFloat const kAnimationDuration = .05;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processCountry:(NSString *)countryId
|
||||
downloadedBytes:(uint64_t)downloadedBytes
|
||||
totalBytes:(uint64_t)totalBytes
|
||||
- (void)processCountry:(NSString *)countryId downloadedBytes:(uint64_t)downloadedBytes totalBytes:(uint64_t)totalBytes
|
||||
{
|
||||
if (!self.rightButton.hidden ||
|
||||
find(m_countries.begin(), m_countries.end(), countryId.UTF8String) == m_countries.end())
|
||||
return;
|
||||
auto const overallProgress = GetFramework().GetStorage().GetOverallProgress(m_countries);
|
||||
CGFloat const progressValue =
|
||||
static_cast<CGFloat>(overallProgress.m_bytesDownloaded) / overallProgress.m_bytesTotal;
|
||||
CGFloat const progressValue = static_cast<CGFloat>(overallProgress.m_bytesDownloaded) / overallProgress.m_bytesTotal;
|
||||
self.progress.progress = progressValue;
|
||||
self.titleLabel.text = [NSString stringWithFormat:@"%@%@%%", L(@"downloading"), @(floor(progressValue * 100))];
|
||||
}
|
||||
@@ -210,10 +206,7 @@ CGFloat const kAnimationDuration = .05;
|
||||
self.rightButton.hidden = YES;
|
||||
self.dialogsBottomOffset.priority = UILayoutPriorityDefaultHigh;
|
||||
self.progressWrapperBottomOffset.priority = UILayoutPriorityDefaultHigh;
|
||||
[UIView animateWithDuration:kAnimationDuration
|
||||
animations:^{
|
||||
[self layoutSubviews];
|
||||
}];
|
||||
[UIView animateWithDuration:kAnimationDuration animations:^{ [self layoutSubviews]; }];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -226,12 +219,9 @@ CGFloat const kAnimationDuration = .05;
|
||||
{
|
||||
_listExpanded = listExpanded;
|
||||
[self layoutIfNeeded];
|
||||
auto const updateCells = ^(BOOL show)
|
||||
{
|
||||
auto const updateCells = ^(BOOL show) {
|
||||
for (MWMDownloaderDialogCell * cell in self.dialogsTableView.visibleCells)
|
||||
{
|
||||
cell.titleLabel.alpha = show ? 1. : 0.;
|
||||
}
|
||||
[self.dialogsTableView refresh];
|
||||
};
|
||||
if (listExpanded)
|
||||
@@ -240,9 +230,9 @@ CGFloat const kAnimationDuration = .05;
|
||||
CGFloat const height = [self bounded:actualHeight withHeight:self.superview.height];
|
||||
self.tableViewHeight.constant = height;
|
||||
self.dialogsTableView.scrollEnabled = actualHeight > self.tableViewHeight.constant;
|
||||
[UIView animateWithDuration:kAnimationDuration animations:^{ [self layoutSubviews]; }
|
||||
completion:^(BOOL finished)
|
||||
{
|
||||
[UIView animateWithDuration:kAnimationDuration
|
||||
animations:^{ [self layoutSubviews]; }
|
||||
completion:^(BOOL finished) {
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^{ updateCells(YES); }];
|
||||
}];
|
||||
}
|
||||
@@ -279,7 +269,9 @@ CGFloat const kAnimationDuration = .05;
|
||||
|
||||
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
|
||||
{
|
||||
CGFloat const height = UIInterfaceOrientationIsLandscape(orientation) ? MIN(self.superview.width, self.superview.height) : MAX(self.superview.width, self.superview.height);
|
||||
CGFloat const height = UIInterfaceOrientationIsLandscape(orientation)
|
||||
? MIN(self.superview.width, self.superview.height)
|
||||
: MAX(self.superview.width, self.superview.height);
|
||||
[self invalidateTableConstraintWithHeight:height];
|
||||
}
|
||||
|
||||
@@ -321,8 +313,8 @@ CGFloat const kAnimationDuration = .05;
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Class cls = [MWMDownloaderDialogCell class];
|
||||
auto cell = static_cast<MWMDownloaderDialogCell *>(
|
||||
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
|
||||
auto cell = static_cast<MWMDownloaderDialogCell *>([tableView dequeueReusableCellWithCellClass:cls
|
||||
indexPath:indexPath]);
|
||||
cell.titleLabel.text = self.countriesNames[indexPath.row];
|
||||
return cell;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ static NSString * const kDownloaderDialogHeaderNibName = @"MWMDownloaderDialogHe
|
||||
+ (instancetype)headerForOwnerAlert:(MWMDownloadTransitMapAlert *)alert
|
||||
{
|
||||
MWMDownloaderDialogHeader * header =
|
||||
[NSBundle.mainBundle loadNibNamed:kDownloaderDialogHeaderNibName owner:nil options:nil]
|
||||
.firstObject;
|
||||
[NSBundle.mainBundle loadNibNamed:kDownloaderDialogHeaderNibName owner:nil options:nil].firstObject;
|
||||
header.ownerAlert = alert;
|
||||
return header;
|
||||
}
|
||||
@@ -30,9 +29,10 @@ static NSString * const kDownloaderDialogHeaderNibName = @"MWMDownloaderDialogHe
|
||||
BOOL const currentState = sender.selected;
|
||||
sender.selected = !currentState;
|
||||
self.dividerView.hidden = currentState;
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^
|
||||
{
|
||||
self.expandImage.transform = sender.selected ? CGAffineTransformMakeRotation(M_PI) : CGAffineTransformIdentity;
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
self.expandImage.transform =
|
||||
sender.selected ? CGAffineTransformMakeRotation(M_PI) : CGAffineTransformIdentity;
|
||||
}];
|
||||
[self.ownerAlert showDownloadDetail:sender];
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
#import "MWMAddPlaceNavigationBar.h"
|
||||
#import "MWMMapDownloadDialog.h"
|
||||
#import "MWMMapViewControlsManager+AddPlace.h"
|
||||
#import "MWMMapWidgetsHelper.h"
|
||||
#import "MWMNetworkPolicy+UI.h"
|
||||
#import "MWMPlacePageManager.h"
|
||||
#import "MWMPlacePageProtocol.h"
|
||||
#import "MWMSideButtons.h"
|
||||
#import "MWMTrafficButtonViewController.h"
|
||||
#import "MWMMapWidgetsHelper.h"
|
||||
#import "MapViewController.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "SwiftBridge.h"
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
#include "map/place_page_info.hpp"
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
NSString * const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
} // namespace
|
||||
|
||||
@@ -45,11 +46,13 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
@implementation MWMMapViewControlsManager
|
||||
|
||||
+ (MWMMapViewControlsManager *)manager {
|
||||
+ (MWMMapViewControlsManager *)manager
|
||||
{
|
||||
return [MapViewController sharedController].controlsManager;
|
||||
}
|
||||
|
||||
- (instancetype)initWithParentController:(MapViewController *)controller {
|
||||
- (instancetype)initWithParentController:(MapViewController *)controller
|
||||
{
|
||||
if (!controller)
|
||||
return nil;
|
||||
self = [super init];
|
||||
@@ -67,7 +70,8 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
BOOL const isNavigationUnderStatusBar = self.navigationManager.state != MWMNavigationDashboardStateHidden &&
|
||||
self.navigationManager.state != MWMNavigationDashboardStateNavigation;
|
||||
BOOL const isMenuViewUnderStatusBar = self.menuState == MWMBottomMenuStateActive;
|
||||
@@ -75,21 +79,22 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
BOOL const isAddPlaceUnderStatusBar =
|
||||
[self.ownerController.view hasSubviewWithViewClass:[MWMAddPlaceNavigationBar class]];
|
||||
BOOL const isNightMode = [UIColor isNightMode];
|
||||
BOOL const isSomethingUnderStatusBar = isNavigationUnderStatusBar ||
|
||||
isDirectionViewUnderStatusBar || isMenuViewUnderStatusBar ||
|
||||
isAddPlaceUnderStatusBar;
|
||||
BOOL const isSomethingUnderStatusBar = isNavigationUnderStatusBar || isDirectionViewUnderStatusBar ||
|
||||
isMenuViewUnderStatusBar || isAddPlaceUnderStatusBar;
|
||||
|
||||
return isSomethingUnderStatusBar || isNightMode ? UIStatusBarStyleLightContent : UIStatusBarStyleDefault;
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (UIView *)anchorView {
|
||||
- (UIView *)anchorView
|
||||
{
|
||||
return self.tabBarController.view;
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
||||
{
|
||||
[self.trafficButton viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
[self.trackRecordingButton viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
[self.tabBarController viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
@@ -97,14 +102,16 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
#pragma mark - MWMPlacePageViewManager
|
||||
|
||||
- (void)searchOnMap:(SearchQuery *)query {
|
||||
- (void)searchOnMap:(SearchQuery *)query
|
||||
{
|
||||
if (![self search:query])
|
||||
return;
|
||||
|
||||
[self.searchManager startSearchingWithIsRouting:NO];
|
||||
}
|
||||
|
||||
- (BOOL)search:(SearchQuery *)query {
|
||||
- (BOOL)search:(SearchQuery *)query
|
||||
{
|
||||
if (query.text.length == 0)
|
||||
return NO;
|
||||
|
||||
@@ -114,21 +121,25 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
}
|
||||
|
||||
#pragma mark - BottomMenu
|
||||
- (void)actionDownloadMaps:(MWMMapDownloaderMode)mode {
|
||||
- (void)actionDownloadMaps:(MWMMapDownloaderMode)mode
|
||||
{
|
||||
[self.ownerController openMapsDownloader:mode];
|
||||
}
|
||||
|
||||
- (void)didFinishAddingPlace {
|
||||
- (void)didFinishAddingPlace
|
||||
{
|
||||
self.isAddingPlace = NO;
|
||||
self.trafficButtonHidden = NO;
|
||||
self.menuState = MWMBottomMenuStateInactive;
|
||||
}
|
||||
|
||||
- (void)addPlace {
|
||||
- (void)addPlace
|
||||
{
|
||||
[self addPlace:NO position:nullptr];
|
||||
}
|
||||
|
||||
- (void)addPlace:(BOOL)isBusiness position:(m2::PointD const *)optionalPosition {
|
||||
- (void)addPlace:(BOOL)isBusiness position:(m2::PointD const *)optionalPosition
|
||||
{
|
||||
MapViewController * ownerController = self.ownerController;
|
||||
|
||||
self.isAddingPlace = YES;
|
||||
@@ -149,15 +160,14 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
[self didFinishAddingPlace];
|
||||
}
|
||||
cancelBlock:^{
|
||||
[self didFinishAddingPlace];
|
||||
}];
|
||||
cancelBlock:^{ [self didFinishAddingPlace]; }];
|
||||
[ownerController setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
|
||||
#pragma mark - MWMNavigationDashboardManager
|
||||
|
||||
- (void)setDisableStandbyOnRouteFollowing:(BOOL)disableStandbyOnRouteFollowing {
|
||||
- (void)setDisableStandbyOnRouteFollowing:(BOOL)disableStandbyOnRouteFollowing
|
||||
{
|
||||
if (_disableStandbyOnRouteFollowing == disableStandbyOnRouteFollowing)
|
||||
return;
|
||||
_disableStandbyOnRouteFollowing = disableStandbyOnRouteFollowing;
|
||||
@@ -169,7 +179,8 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
#pragma mark - Routing
|
||||
|
||||
- (void)onRoutePrepare {
|
||||
- (void)onRoutePrepare
|
||||
{
|
||||
auto nm = self.navigationManager;
|
||||
[nm onRoutePrepare];
|
||||
[nm onRoutePointsUpdated];
|
||||
@@ -177,18 +188,21 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
self.promoButton.hidden = YES;
|
||||
}
|
||||
|
||||
- (void)onRouteRebuild {
|
||||
- (void)onRouteRebuild
|
||||
{
|
||||
[self.ownerController.bookmarksCoordinator close];
|
||||
[self.navigationManager onRoutePlanning];
|
||||
self.promoButton.hidden = YES;
|
||||
}
|
||||
|
||||
- (void)onRouteReady:(BOOL)hasWarnings {
|
||||
- (void)onRouteReady:(BOOL)hasWarnings
|
||||
{
|
||||
[self.navigationManager onRouteReady:hasWarnings];
|
||||
self.promoButton.hidden = YES;
|
||||
}
|
||||
|
||||
- (void)onRouteStart {
|
||||
- (void)onRouteStart
|
||||
{
|
||||
self.hidden = NO;
|
||||
self.sideButtons.zoomHidden = self.zoomHidden;
|
||||
self.sideButtonsHidden = NO;
|
||||
@@ -198,7 +212,8 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
self.promoButton.hidden = YES;
|
||||
}
|
||||
|
||||
- (void)onRouteStop {
|
||||
- (void)onRouteStop
|
||||
{
|
||||
self.sideButtons.zoomHidden = self.zoomHidden;
|
||||
[self.navigationManager onRouteStop];
|
||||
self.disableStandbyOnRouteFollowing = NO;
|
||||
@@ -208,20 +223,24 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (MWMSideButtons *)sideButtons {
|
||||
- (MWMSideButtons *)sideButtons
|
||||
{
|
||||
if (!_sideButtons)
|
||||
_sideButtons = [[MWMSideButtons alloc] initWithParentView:self.ownerController.controlsView];
|
||||
return _sideButtons;
|
||||
}
|
||||
|
||||
- (MWMTrafficButtonViewController *)trafficButton {
|
||||
- (MWMTrafficButtonViewController *)trafficButton
|
||||
{
|
||||
if (!_trafficButton)
|
||||
_trafficButton = [[MWMTrafficButtonViewController alloc] init];
|
||||
return _trafficButton;
|
||||
}
|
||||
|
||||
- (BottomTabBarViewController *)tabBarController {
|
||||
if (!_tabBarController) {
|
||||
- (BottomTabBarViewController *)tabBarController
|
||||
{
|
||||
if (!_tabBarController)
|
||||
{
|
||||
MapViewController * ownerController = _ownerController;
|
||||
_tabBarController = [BottomTabBarBuilder buildWithMapViewController:ownerController controlsManager:self];
|
||||
[ownerController addChildViewController:_tabBarController];
|
||||
@@ -232,13 +251,15 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
return _tabBarController;
|
||||
}
|
||||
|
||||
- (id<MWMPlacePageProtocol>)placePageManager {
|
||||
- (id<MWMPlacePageProtocol>)placePageManager
|
||||
{
|
||||
if (!_placePageManager)
|
||||
_placePageManager = [[MWMPlacePageManager alloc] init];
|
||||
return _placePageManager;
|
||||
}
|
||||
|
||||
- (MWMNavigationDashboardManager *)navigationManager {
|
||||
- (MWMNavigationDashboardManager *)navigationManager
|
||||
{
|
||||
if (!_navigationManager)
|
||||
_navigationManager = [[MWMNavigationDashboardManager alloc] initWithParentView:self.ownerController.controlsView];
|
||||
return _navigationManager;
|
||||
@@ -246,7 +267,8 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
|
||||
@synthesize menuState = _menuState;
|
||||
|
||||
- (void)setHidden:(BOOL)hidden {
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
if (_hidden == hidden)
|
||||
return;
|
||||
// Do not hide the controls view during the place adding process.
|
||||
@@ -257,40 +279,44 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
self.menuState = hidden ? MWMBottomMenuStateHidden : MWMBottomMenuStateInactive;
|
||||
}
|
||||
|
||||
- (void)setZoomHidden:(BOOL)zoomHidden {
|
||||
- (void)setZoomHidden:(BOOL)zoomHidden
|
||||
{
|
||||
_zoomHidden = zoomHidden;
|
||||
self.sideButtons.zoomHidden = zoomHidden;
|
||||
}
|
||||
|
||||
- (void)setSideButtonsHidden:(BOOL)sideButtonsHidden {
|
||||
- (void)setSideButtonsHidden:(BOOL)sideButtonsHidden
|
||||
{
|
||||
_sideButtonsHidden = sideButtonsHidden;
|
||||
self.sideButtons.hidden = self.hidden || sideButtonsHidden;
|
||||
}
|
||||
|
||||
- (void)setTrafficButtonHidden:(BOOL)trafficButtonHidden {
|
||||
- (void)setTrafficButtonHidden:(BOOL)trafficButtonHidden
|
||||
{
|
||||
BOOL const isNavigation = self.navigationManager.state == MWMNavigationDashboardStateNavigation;
|
||||
_trafficButtonHidden = isNavigation || trafficButtonHidden;
|
||||
self.trafficButton.hidden = self.hidden || _trafficButtonHidden;
|
||||
}
|
||||
|
||||
- (void)setTrackRecordingButtonState:(TrackRecordingButtonState)state {
|
||||
if (!_trackRecordingButton) {
|
||||
- (void)setTrackRecordingButtonState:(TrackRecordingButtonState)state
|
||||
{
|
||||
if (!_trackRecordingButton)
|
||||
_trackRecordingButton = [[TrackRecordingButtonViewController alloc] init];
|
||||
}
|
||||
[self.trackRecordingButton setState:state completion:^{
|
||||
[MWMMapWidgetsHelper updateLayoutForAvailableArea];
|
||||
}];
|
||||
[self.trackRecordingButton setState:state completion:^{ [MWMMapWidgetsHelper updateLayoutForAvailableArea]; }];
|
||||
if (state == TrackRecordingButtonStateClosed)
|
||||
_trackRecordingButton = nil;
|
||||
}
|
||||
|
||||
- (void)setMenuState:(MWMBottomMenuState)menuState {
|
||||
- (void)setMenuState:(MWMBottomMenuState)menuState
|
||||
{
|
||||
_menuState = menuState;
|
||||
MapViewController * ownerController = _ownerController;
|
||||
switch (_menuState) {
|
||||
switch (_menuState)
|
||||
{
|
||||
case MWMBottomMenuStateActive:
|
||||
_tabBarController.isHidden = NO;
|
||||
if (_menuController == nil) {
|
||||
if (_menuController == nil)
|
||||
{
|
||||
_menuController = [BottomMenuBuilder buildMenuWithMapViewController:ownerController
|
||||
controlsManager:self
|
||||
delegate:self];
|
||||
@@ -299,7 +325,8 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
break;
|
||||
case MWMBottomMenuStateLayers:
|
||||
_tabBarController.isHidden = NO;
|
||||
if (_menuController == nil) {
|
||||
if (_menuController == nil)
|
||||
{
|
||||
_menuController = [BottomMenuBuilder buildLayersWithMapViewController:ownerController
|
||||
controlsManager:self
|
||||
delegate:self];
|
||||
@@ -308,26 +335,28 @@ NSString *const kMapToCategorySelectorSegue = @"MapToCategorySelectorSegue";
|
||||
break;
|
||||
case MWMBottomMenuStateInactive:
|
||||
_tabBarController.isHidden = NO;
|
||||
if (_menuController != nil) {
|
||||
if (_menuController != nil)
|
||||
{
|
||||
[_menuController dismissViewControllerAnimated:YES completion:nil];
|
||||
_menuController = nil;
|
||||
}
|
||||
break;
|
||||
case MWMBottomMenuStateHidden:
|
||||
_tabBarController.isHidden = YES;
|
||||
if (_menuController != nil) {
|
||||
if (_menuController != nil)
|
||||
{
|
||||
[_menuController dismissViewControllerAnimated:YES completion:nil];
|
||||
_menuController = nil;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - MWMFeatureHolder
|
||||
|
||||
- (id<MWMFeatureHolder>)featureHolder {
|
||||
- (id<MWMFeatureHolder>)featureHolder
|
||||
{
|
||||
return self.placePageManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +37,15 @@ NSString * const kUDDidShowLongTapToShowSideButtonsToast = @"kUDDidShowLongTapTo
|
||||
|
||||
@implementation MWMSideButtons
|
||||
|
||||
- (UIView *)view {
|
||||
- (UIView *)view
|
||||
{
|
||||
return self.sideView;
|
||||
}
|
||||
|
||||
+ (MWMSideButtons *)buttons { return [MWMMapViewControlsManager manager].sideButtons; }
|
||||
+ (MWMSideButtons *)buttons
|
||||
{
|
||||
return [MWMMapViewControlsManager manager].sideButtons;
|
||||
}
|
||||
- (instancetype)initWithParentView:(UIView *)view
|
||||
{
|
||||
self = [super init];
|
||||
@@ -56,7 +60,10 @@ NSString * const kUDDidShowLongTapToShowSideButtonsToast = @"kUDDidShowLongTapTo
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)updateAvailableArea:(CGRect)frame { [[self buttons].sideView updateAvailableArea:frame]; }
|
||||
+ (void)updateAvailableArea:(CGRect)frame
|
||||
{
|
||||
[[self buttons].sideView updateAvailableArea:frame];
|
||||
}
|
||||
|
||||
- (void)zoomIn
|
||||
{
|
||||
@@ -97,7 +104,10 @@ NSString * const kUDDidShowLongTapToShowSideButtonsToast = @"kUDDidShowLongTapTo
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)zoomTouchDown:(UIButton *)sender { self.zoomSwipeEnabled = YES; }
|
||||
- (IBAction)zoomTouchDown:(UIButton *)sender
|
||||
{
|
||||
self.zoomSwipeEnabled = YES;
|
||||
}
|
||||
- (IBAction)zoomTouchUpInside:(UIButton *)sender
|
||||
{
|
||||
self.zoomSwipeEnabled = NO;
|
||||
@@ -107,14 +117,16 @@ NSString * const kUDDidShowLongTapToShowSideButtonsToast = @"kUDDidShowLongTapTo
|
||||
[self zoomOut];
|
||||
}
|
||||
|
||||
- (IBAction)zoomTouchUpOutside:(UIButton *)sender { self.zoomSwipeEnabled = NO; }
|
||||
- (IBAction)zoomTouchUpOutside:(UIButton *)sender
|
||||
{
|
||||
self.zoomSwipeEnabled = NO;
|
||||
}
|
||||
- (IBAction)zoomSwipe:(UIPanGestureRecognizer *)sender
|
||||
{
|
||||
if (!self.zoomSwipeEnabled)
|
||||
return;
|
||||
UIView * const superview = self.sideView.superview;
|
||||
CGFloat const translation =
|
||||
-[sender translationInView:superview].y / superview.bounds.size.height;
|
||||
CGFloat const translation = -[sender translationInView:superview].y / superview.bounds.size.height;
|
||||
|
||||
CGFloat const scaleFactor = exp(translation);
|
||||
GetFramework().Scale(scaleFactor, false);
|
||||
@@ -128,7 +140,10 @@ NSString * const kUDDidShowLongTapToShowSideButtonsToast = @"kUDDidShowLongTapTo
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (BOOL)zoomHidden { return self.sideView.zoomHidden; }
|
||||
- (BOOL)zoomHidden
|
||||
{
|
||||
return self.sideView.zoomHidden;
|
||||
}
|
||||
- (void)setZoomHidden:(BOOL)zoomHidden
|
||||
{
|
||||
if ([MWMRouter isRoutingActive])
|
||||
@@ -137,7 +152,10 @@ NSString * const kUDDidShowLongTapToShowSideButtonsToast = @"kUDDidShowLongTapTo
|
||||
self.sideView.zoomHidden = [MWMSettings zoomButtonsEnabled] ? zoomHidden : YES;
|
||||
}
|
||||
|
||||
- (BOOL)hidden { return self.sideView.hidden; }
|
||||
- (BOOL)hidden
|
||||
{
|
||||
return self.sideView.hidden;
|
||||
}
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
if (!self.hidden && hidden)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#import "MWMSideButtonsView.h"
|
||||
#import "MWMButton.h"
|
||||
#import "MWMRouter.h"
|
||||
#import "MWMMapViewControlsCommon.h"
|
||||
#import "MWMRouter.h"
|
||||
|
||||
#include "base/math.hpp"
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
CGFloat const kLocationButtonSpacingMax = 52;
|
||||
CGFloat const kLocationButtonSpacingMin = 8;
|
||||
CGFloat const kButtonsTopOffset = 6;
|
||||
@@ -24,16 +25,22 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
|
||||
@implementation MWMSideButtonsView
|
||||
|
||||
- (void)awakeFromNib {
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
CGFloat spacing = self.availableHeight - self.zoomOut.maxY - self.location.height;
|
||||
spacing = math::Clamp(spacing, kLocationButtonSpacingMin, kLocationButtonSpacingMax);
|
||||
|
||||
if (!IPAD && (UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeLeft || UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeRight) && [MWMRouter isRoutingActive]) {
|
||||
if (!IPAD &&
|
||||
(UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeLeft ||
|
||||
UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeRight) &&
|
||||
[MWMRouter isRoutingActive])
|
||||
{
|
||||
spacing = spacing - 36;
|
||||
}
|
||||
|
||||
@@ -47,14 +54,18 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)layoutXPosition:(BOOL)hidden {
|
||||
if (UIApplication.sharedApplication.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
|
||||
- (void)layoutXPosition:(BOOL)hidden
|
||||
{
|
||||
if (UIApplication.sharedApplication.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft)
|
||||
{
|
||||
if (hidden)
|
||||
self.maxX = 0;
|
||||
else
|
||||
self.minX = self.availableArea.origin.x + kViewControlsOffsetToBounds;
|
||||
} else {
|
||||
const auto availableAreaMaxX = self.availableArea.origin.x + self.availableArea.size.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const availableAreaMaxX = self.availableArea.origin.x + self.availableArea.size.width;
|
||||
if (hidden)
|
||||
self.minX = self.superview.width;
|
||||
else
|
||||
@@ -62,20 +73,21 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutYPosition {
|
||||
- (void)layoutYPosition
|
||||
{
|
||||
CGFloat const centerShift = (self.height - self.zoomIn.midY - self.zoomOut.midY) / 2;
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
self.midY = centerShift + self.superview.height / 2;
|
||||
if ([MWMRouter isRoutingActive]) {
|
||||
if ([MWMRouter isRoutingActive])
|
||||
self.midY = self.midY - 18;
|
||||
}
|
||||
if (self.maxY > self.bottomBound)
|
||||
self.maxY = self.bottomBound;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)fadeZoomButtonsShow:(BOOL)show {
|
||||
- (void)fadeZoomButtonsShow:(BOOL)show
|
||||
{
|
||||
CGFloat const alpha = show ? 1.0 : 0.0;
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
@@ -84,15 +96,14 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)fadeLocationButtonShow:(BOOL)show {
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
self.location.alpha = show ? 1.0 : 0.0;
|
||||
}];
|
||||
- (void)fadeLocationButtonShow:(BOOL)show
|
||||
{
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^{ self.location.alpha = show ? 1.0 : 0.0; }];
|
||||
}
|
||||
|
||||
// Show/hide zoom and location buttons depending on available vertical space.
|
||||
- (void)animate {
|
||||
- (void)animate
|
||||
{
|
||||
[self layoutYPosition];
|
||||
|
||||
BOOL const isZoomHidden = self.zoomIn.alpha == 0.0;
|
||||
@@ -108,15 +119,18 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setZoomHidden:(BOOL)zoomHidden {
|
||||
- (void)setZoomHidden:(BOOL)zoomHidden
|
||||
{
|
||||
_zoomHidden = zoomHidden;
|
||||
self.zoomIn.hidden = zoomHidden;
|
||||
self.zoomOut.hidden = zoomHidden;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)setHidden:(BOOL)hidden animated:(BOOL)animated {
|
||||
if (animated) {
|
||||
- (void)setHidden:(BOOL)hidden animated:(BOOL)animated
|
||||
{
|
||||
if (animated)
|
||||
{
|
||||
if (self.hidden == hidden)
|
||||
return;
|
||||
// Side buttons should be visible during any our show/hide anamation.
|
||||
@@ -127,15 +141,16 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
self.alpha = hidden ? 0.0 : 1.0;
|
||||
[self layoutXPosition:hidden];
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
self.hidden = hidden;
|
||||
}];
|
||||
} else {
|
||||
completion:^(BOOL finished) { self.hidden = hidden; }];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.hidden = hidden;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateAvailableArea:(CGRect)frame {
|
||||
- (void)updateAvailableArea:(CGRect)frame
|
||||
{
|
||||
if (CGRectEqualToRect(self.availableArea, frame))
|
||||
return;
|
||||
// If during our show/hide animation position is changed it is corrupted.
|
||||
@@ -155,14 +170,17 @@ CGFloat const kButtonsBottomOffset = 6;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (CGFloat)availableHeight {
|
||||
- (CGFloat)availableHeight
|
||||
{
|
||||
return self.availableArea.size.height - kButtonsTopOffset - kButtonsBottomOffset;
|
||||
}
|
||||
|
||||
- (CGFloat)topBound {
|
||||
- (CGFloat)topBound
|
||||
{
|
||||
return self.availableArea.origin.y + kButtonsTopOffset;
|
||||
}
|
||||
- (CGFloat)bottomBound {
|
||||
- (CGFloat)bottomBound
|
||||
{
|
||||
auto const area = self.availableArea;
|
||||
return area.origin.y + area.size.height - kButtonsBottomOffset;
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
#import "MWMZoomButtonsView.h"
|
||||
#import "Statistics.h"
|
||||
|
||||
|
||||
#include "Framework.h"
|
||||
#include "platform/settings.hpp"
|
||||
#include "indexer/scales.hpp"
|
||||
#include "platform/settings.hpp"
|
||||
|
||||
static NSString * const kMWMZoomButtonsViewNibName = @"MWMZoomButtonsView";
|
||||
|
||||
|
||||
@interface MWMZoomButtons ()
|
||||
|
||||
@property(nonatomic) IBOutlet MWMZoomButtonsView * zoomView;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import "Common.h"
|
||||
#import "MWMZoomButtonsView.h"
|
||||
#import "Common.h"
|
||||
#import "MWMMapViewControlsCommon.h"
|
||||
|
||||
static CGFloat const kZoomViewOffsetToTopBound = 12.0;
|
||||
@@ -39,7 +39,8 @@ static CGFloat const kZoomViewHideBoundPercent = 0.4;
|
||||
|
||||
- (void)layoutYPosition
|
||||
{
|
||||
CGFloat const maxY = MIN(self.superview.height - kZoomViewOffsetToFrameBound, self.bottomBound - kZoomViewOffsetToBottomBound);
|
||||
CGFloat const maxY =
|
||||
MIN(self.superview.height - kZoomViewOffsetToFrameBound, self.bottomBound - kZoomViewOffsetToBottomBound);
|
||||
self.minY = MAX(maxY - self.height, self.topBound + kZoomViewOffsetToTopBound);
|
||||
}
|
||||
|
||||
@@ -59,7 +60,8 @@ static CGFloat const kZoomViewHideBoundPercent = 0.4;
|
||||
{
|
||||
CGFloat const hideBound = kZoomViewHideBoundPercent * self.superview.height;
|
||||
BOOL const isHidden = self.alpha == 0.0;
|
||||
BOOL const willHide = (self.bottomBound < hideBound) || (self.defaultBounds.size.height > self.bottomBound - self.topBound);
|
||||
BOOL const willHide =
|
||||
(self.bottomBound < hideBound) || (self.defaultBounds.size.height > self.bottomBound - self.topBound);
|
||||
if (willHide)
|
||||
{
|
||||
if (!isHidden)
|
||||
@@ -84,12 +86,9 @@ static CGFloat const kZoomViewHideBoundPercent = 0.4;
|
||||
if (!hidden)
|
||||
self.hidden = NO;
|
||||
[self layoutXPosition:!hidden];
|
||||
[UIView animateWithDuration:framesDuration(kMenuViewHideFramesCount) animations:^
|
||||
{
|
||||
[self layoutXPosition:hidden];
|
||||
}
|
||||
completion:^(BOOL finished)
|
||||
{
|
||||
[UIView animateWithDuration:framesDuration(kMenuViewHideFramesCount)
|
||||
animations:^{ [self layoutXPosition:hidden]; }
|
||||
completion:^(BOOL finished) {
|
||||
if (hidden)
|
||||
self.hidden = YES;
|
||||
}];
|
||||
|
||||
@@ -10,14 +10,17 @@
|
||||
#import "SwiftBridge.h"
|
||||
#import "base/assert.hpp"
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
CGFloat const kTopOffset = 6;
|
||||
|
||||
NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
NSArray<UIImage *> * imagesWithName(NSString * name)
|
||||
{
|
||||
NSUInteger const imagesCount = 3;
|
||||
NSMutableArray<UIImage *> * images = [NSMutableArray arrayWithCapacity:imagesCount];
|
||||
NSString * mode = [UIColor isNightMode] ? @"dark" : @"light";
|
||||
for (NSUInteger i = 1; i <= imagesCount; i += 1) {
|
||||
for (NSUInteger i = 1; i <= imagesCount; i += 1)
|
||||
{
|
||||
NSString * imageName = [NSString stringWithFormat:@"%@_%@_%@", name, mode, @(i).stringValue];
|
||||
[images addObject:static_cast<UIImage * _Nonnull>([UIImage imageNamed:imageName])];
|
||||
}
|
||||
@@ -41,13 +44,16 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
|
||||
@implementation MWMTrafficButtonViewController
|
||||
|
||||
+ (MWMTrafficButtonViewController *)controller {
|
||||
+ (MWMTrafficButtonViewController *)controller
|
||||
{
|
||||
return [MWMMapViewControlsManager manager].trafficButton;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
MapViewController * ovc = [MapViewController sharedController];
|
||||
[ovc addChildViewController:self];
|
||||
[ovc.controlsView addSubview:self.view];
|
||||
@@ -59,16 +65,19 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
- (void)dealloc
|
||||
{
|
||||
[StyleManager.shared removeListener:self];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
[Toast hideAll];
|
||||
}
|
||||
|
||||
- (void)configLayout {
|
||||
- (void)configLayout
|
||||
{
|
||||
UIView * sv = self.view;
|
||||
UIView * ov = sv.superview;
|
||||
|
||||
@@ -78,12 +87,14 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
self.leftOffset.active = YES;
|
||||
}
|
||||
|
||||
- (void)setHidden:(BOOL)hidden {
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
_hidden = hidden;
|
||||
[self refreshLayout];
|
||||
}
|
||||
|
||||
- (void)refreshLayout {
|
||||
- (void)refreshLayout
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
auto const availableArea = self.availableArea;
|
||||
auto const fitInAvailableArea = CGRectGetMaxY(self.view.frame) < CGRectGetMaxY(availableArea) + kTopOffset;
|
||||
@@ -97,24 +108,20 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
});
|
||||
}
|
||||
|
||||
- (void)handleTrafficState:(MWMMapOverlayTrafficState)state {
|
||||
- (void)handleTrafficState:(MWMMapOverlayTrafficState)state
|
||||
{
|
||||
MWMButton * btn = (MWMButton *)self.view;
|
||||
UIImageView * iv = btn.imageView;
|
||||
switch (state) {
|
||||
case MWMMapOverlayTrafficStateDisabled:
|
||||
CHECK(false, ("Incorrect traffic manager state."));
|
||||
break;
|
||||
case MWMMapOverlayTrafficStateEnabled:
|
||||
btn.imageName = @"btn_traffic_on";
|
||||
break;
|
||||
switch (state)
|
||||
{
|
||||
case MWMMapOverlayTrafficStateDisabled: CHECK(false, ("Incorrect traffic manager state.")); break;
|
||||
case MWMMapOverlayTrafficStateEnabled: btn.imageName = @"btn_traffic_on"; break;
|
||||
case MWMMapOverlayTrafficStateWaitingData:
|
||||
iv.animationImages = imagesWithName(@"btn_traffic_update");
|
||||
iv.animationDuration = 0.8;
|
||||
[iv startAnimating];
|
||||
break;
|
||||
case MWMMapOverlayTrafficStateOutdated:
|
||||
btn.imageName = @"btn_traffic_outdated";
|
||||
break;
|
||||
case MWMMapOverlayTrafficStateOutdated: btn.imageName = @"btn_traffic_outdated"; break;
|
||||
case MWMMapOverlayTrafficStateNoData:
|
||||
btn.imageName = @"btn_traffic_on";
|
||||
[Toast showWithText:L(@"traffic_data_unavailable")];
|
||||
@@ -134,10 +141,11 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleIsolinesState:(MWMMapOverlayIsolinesState)state {
|
||||
switch (state) {
|
||||
case MWMMapOverlayIsolinesStateDisabled:
|
||||
break;
|
||||
- (void)handleIsolinesState:(MWMMapOverlayIsolinesState)state
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case MWMMapOverlayIsolinesStateDisabled: break;
|
||||
case MWMMapOverlayIsolinesStateEnabled:
|
||||
if (![MWMMapOverlayManager isolinesVisible])
|
||||
[Toast showWithText:L(@"isolines_toast_zooms_1_10")];
|
||||
@@ -153,46 +161,58 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applyTheme {
|
||||
- (void)applyTheme
|
||||
{
|
||||
MWMButton * btn = static_cast<MWMButton *>(self.view);
|
||||
UIImageView * iv = btn.imageView;
|
||||
|
||||
// Traffic state machine: https://confluence.mail.ru/pages/viewpage.action?pageId=103680959
|
||||
[iv stopAnimating];
|
||||
if ([MWMMapOverlayManager trafficEnabled]) {
|
||||
if ([MWMMapOverlayManager trafficEnabled])
|
||||
{
|
||||
[self handleTrafficState:[MWMMapOverlayManager trafficState]];
|
||||
} else if ([MWMMapOverlayManager transitEnabled]) {
|
||||
}
|
||||
else if ([MWMMapOverlayManager transitEnabled])
|
||||
{
|
||||
btn.imageName = @"btn_subway_on";
|
||||
if ([MWMMapOverlayManager transitState] == MWMMapOverlayTransitStateNoData)
|
||||
[Toast showWithText:L(@"subway_data_unavailable")];
|
||||
} else if ([MWMMapOverlayManager isoLinesEnabled]) {
|
||||
}
|
||||
else if ([MWMMapOverlayManager isoLinesEnabled])
|
||||
{
|
||||
btn.imageName = @"btn_isoMap_on";
|
||||
[self handleIsolinesState:[MWMMapOverlayManager isolinesState]];
|
||||
} else if ([MWMMapOverlayManager outdoorEnabled]) {
|
||||
}
|
||||
else if ([MWMMapOverlayManager outdoorEnabled])
|
||||
{
|
||||
btn.imageName = @"btn_isoMap_on";
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
btn.imageName = @"btn_layers";
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)buttonTouchUpInside {
|
||||
BOOL needsToDisableMapLayer =
|
||||
[MWMMapOverlayManager trafficEnabled] ||
|
||||
[MWMMapOverlayManager transitEnabled] ||
|
||||
[MWMMapOverlayManager isoLinesEnabled] ||
|
||||
[MWMMapOverlayManager outdoorEnabled];
|
||||
- (IBAction)buttonTouchUpInside
|
||||
{
|
||||
BOOL needsToDisableMapLayer = [MWMMapOverlayManager trafficEnabled] || [MWMMapOverlayManager transitEnabled] ||
|
||||
[MWMMapOverlayManager isoLinesEnabled] || [MWMMapOverlayManager outdoorEnabled];
|
||||
|
||||
if (needsToDisableMapLayer) {
|
||||
if (needsToDisableMapLayer)
|
||||
{
|
||||
[MWMMapOverlayManager setTrafficEnabled:NO];
|
||||
[MWMMapOverlayManager setTransitEnabled:NO];
|
||||
[MWMMapOverlayManager setIsoLinesEnabled:NO];
|
||||
[MWMMapOverlayManager setOutdoorEnabled:NO];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
MWMMapViewControlsManager.manager.menuState = MWMBottomMenuStateLayers;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)updateAvailableArea:(CGRect)frame {
|
||||
+ (void)updateAvailableArea:(CGRect)frame
|
||||
{
|
||||
auto controller = [self controller];
|
||||
if (CGRectEqualToRect(controller.availableArea, frame))
|
||||
return;
|
||||
@@ -202,16 +222,20 @@ NSArray<UIImage *> *imagesWithName(NSString *name) {
|
||||
|
||||
#pragma mark - MWMMapOverlayManagerObserver
|
||||
|
||||
- (void)onTrafficStateUpdated {
|
||||
- (void)onTrafficStateUpdated
|
||||
{
|
||||
[self applyTheme];
|
||||
}
|
||||
- (void)onTransitStateUpdated {
|
||||
- (void)onTransitStateUpdated
|
||||
{
|
||||
[self applyTheme];
|
||||
}
|
||||
- (void)onIsoLinesStateUpdated {
|
||||
- (void)onIsoLinesStateUpdated
|
||||
{
|
||||
[self applyTheme];
|
||||
}
|
||||
- (void)onOutdoorStateUpdated {
|
||||
- (void)onOutdoorStateUpdated
|
||||
{
|
||||
[self applyTheme];
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#import <AudioToolbox/AudioServices.h>
|
||||
#import <CoreApi/Framework.h>
|
||||
#import <CoreApi/DurationFormatter.h>
|
||||
#import <CoreApi/Framework.h>
|
||||
|
||||
#include "routing/following_info.hpp"
|
||||
#include "routing/turns.hpp"
|
||||
@@ -18,14 +18,17 @@
|
||||
|
||||
#include "geometry/distance_on_sphere.hpp"
|
||||
|
||||
namespace {
|
||||
UIImage * image(routing::turns::CarDirection t, bool isNextTurn) {
|
||||
namespace
|
||||
{
|
||||
UIImage * image(routing::turns::CarDirection t, bool isNextTurn)
|
||||
{
|
||||
if (![MWMLocationManager lastLocation])
|
||||
return nil;
|
||||
|
||||
using namespace routing::turns;
|
||||
NSString * imageName;
|
||||
switch (t) {
|
||||
switch (t)
|
||||
{
|
||||
case CarDirection::ExitHighwayToRight: imageName = @"ic_exit_highway_to_right"; break;
|
||||
case CarDirection::TurnSlightRight: imageName = @"slight_right"; break;
|
||||
case CarDirection::TurnRight: imageName = @"simple_right"; break;
|
||||
@@ -50,13 +53,15 @@ UIImage * image(routing::turns::CarDirection t, bool isNextTurn) {
|
||||
return [UIImage imageNamed:isNextTurn ? [imageName stringByAppendingString:@"_then"] : imageName];
|
||||
}
|
||||
|
||||
UIImage * image(routing::turns::PedestrianDirection t) {
|
||||
UIImage * image(routing::turns::PedestrianDirection t)
|
||||
{
|
||||
if (![MWMLocationManager lastLocation])
|
||||
return nil;
|
||||
|
||||
using namespace routing::turns;
|
||||
NSString * imageName;
|
||||
switch (t) {
|
||||
switch (t)
|
||||
{
|
||||
case PedestrianDirection::TurnRight: imageName = @"simple_right"; break;
|
||||
case PedestrianDirection::TurnLeft: imageName = @"simple_left"; break;
|
||||
case PedestrianDirection::ReachedYourDestination: imageName = @"finish_point"; break;
|
||||
@@ -69,11 +74,13 @@ UIImage * image(routing::turns::PedestrianDirection t) {
|
||||
return [UIImage imageNamed:imageName];
|
||||
}
|
||||
|
||||
NSArray<MWMRouterTransitStepInfo *> *buildRouteTransitSteps(NSArray<MWMRoutePoint *> *points) {
|
||||
NSArray<MWMRouterTransitStepInfo *> * buildRouteTransitSteps(NSArray<MWMRoutePoint *> * points)
|
||||
{
|
||||
// Generate step info in format: (Segment 1 distance) (1) (Segment 2 distance) (2) ... (n-1) (Segment N distance).
|
||||
NSMutableArray<MWMRouterTransitStepInfo *> * steps = [NSMutableArray arrayWithCapacity:[points count] * 2 - 1];
|
||||
auto const numPoints = [points count];
|
||||
for (int i = 0; i < numPoints - 1; i++) {
|
||||
for (int i = 0; i < numPoints - 1; i++)
|
||||
{
|
||||
MWMRoutePoint * segmentStart = points[i];
|
||||
MWMRoutePoint * segmentEnd = points[i + 1];
|
||||
auto const distance = platform::Distance::CreateFormatted(
|
||||
@@ -85,7 +92,8 @@ NSArray<MWMRouterTransitStepInfo *> *buildRouteTransitSteps(NSArray<MWMRoutePoin
|
||||
segmentInfo.distanceUnits = @(distance.GetUnitsString().c_str());
|
||||
steps[i * 2] = segmentInfo;
|
||||
|
||||
if (i < numPoints - 2) {
|
||||
if (i < numPoints - 2)
|
||||
{
|
||||
MWMRouterTransitStepInfo * stopInfo = [[MWMRouterTransitStepInfo alloc] init];
|
||||
stopInfo.type = MWMRouterTransitTypeIntermediatePoint;
|
||||
stopInfo.intermediateIndex = i;
|
||||
@@ -129,25 +137,28 @@ NSArray<MWMRouterTransitStepInfo *> *buildRouteTransitSteps(NSArray<MWMRoutePoin
|
||||
|
||||
+ (NSAttributedString *)estimateDot
|
||||
{
|
||||
auto attributes = @{
|
||||
NSForegroundColorAttributeName: [UIColor blackSecondaryText],
|
||||
NSFontAttributeName: [UIFont medium17]
|
||||
};
|
||||
auto attributes =
|
||||
@{NSForegroundColorAttributeName: [UIColor blackSecondaryText], NSFontAttributeName: [UIFont medium17]};
|
||||
return [[NSAttributedString alloc] initWithString:@" • " attributes:attributes];
|
||||
}
|
||||
|
||||
- (NSAttributedString *)estimate {
|
||||
NSDictionary * primaryAttributes = @{NSForegroundColorAttributeName: [UIColor blackPrimaryText], NSFontAttributeName: [UIFont medium17]};
|
||||
NSDictionary * secondaryAttributes = @{NSForegroundColorAttributeName: [UIColor blackSecondaryText], NSFontAttributeName: [UIFont medium17]};
|
||||
- (NSAttributedString *)estimate
|
||||
{
|
||||
NSDictionary * primaryAttributes =
|
||||
@{NSForegroundColorAttributeName: [UIColor blackPrimaryText], NSFontAttributeName: [UIFont medium17]};
|
||||
NSDictionary * secondaryAttributes =
|
||||
@{NSForegroundColorAttributeName: [UIColor blackSecondaryText], NSFontAttributeName: [UIFont medium17]};
|
||||
|
||||
auto result = [[NSMutableAttributedString alloc] initWithString:@""];
|
||||
if (self.showEta) {
|
||||
if (self.showEta)
|
||||
{
|
||||
NSString * eta = [DurationFormatter durationStringFromTimeInterval:self.timeToTarget];
|
||||
[result appendAttributedString:[[NSMutableAttributedString alloc] initWithString:eta attributes:primaryAttributes]];
|
||||
[result appendAttributedString:MWMNavigationDashboardEntity.estimateDot];
|
||||
}
|
||||
|
||||
if (self.isWalk) {
|
||||
if (self.isWalk)
|
||||
{
|
||||
UIFont * font = primaryAttributes[NSFontAttributeName];
|
||||
auto textAttachment = [[NSTextAttachment alloc] init];
|
||||
auto image = [UIImage imageNamed:@"ic_walk"];
|
||||
@@ -189,14 +200,19 @@ NSArray<MWMRouterTransitStepInfo *> *buildRouteTransitSteps(NSArray<MWMRoutePoin
|
||||
|
||||
@implementation MWMNavigationDashboardManager (Entity)
|
||||
|
||||
- (void)updateFollowingInfo:(routing::FollowingInfo const &)info routePoints:(NSArray<MWMRoutePoint *> *)points type:(MWMRouterType)type {
|
||||
if ([MWMRouter isRouteFinished]) {
|
||||
- (void)updateFollowingInfo:(routing::FollowingInfo const &)info
|
||||
routePoints:(NSArray<MWMRoutePoint *> *)points
|
||||
type:(MWMRouterType)type
|
||||
{
|
||||
if ([MWMRouter isRouteFinished])
|
||||
{
|
||||
[MWMRouter stopRouting];
|
||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto entity = self.entity) {
|
||||
if (auto entity = self.entity)
|
||||
{
|
||||
BOOL const showEta = (type != MWMRouterTypeRuler);
|
||||
|
||||
entity.isValid = YES;
|
||||
@@ -217,9 +233,12 @@ NSArray<MWMRouterTransitStepInfo *> *buildRouteTransitSteps(NSArray<MWMRoutePoin
|
||||
else
|
||||
entity.transitSteps = [[NSArray alloc] init];
|
||||
|
||||
if (type == MWMRouterTypePedestrian) {
|
||||
if (type == MWMRouterTypePedestrian)
|
||||
{
|
||||
entity.turnImage = image(info.m_pedestrianTurn);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
using namespace routing::turns;
|
||||
CarDirection const turn = info.m_turn;
|
||||
entity.turnImage = image(turn, false);
|
||||
@@ -236,8 +255,10 @@ NSArray<MWMRouterTransitStepInfo *> *buildRouteTransitSteps(NSArray<MWMRoutePoin
|
||||
[self onNavigationInfoUpdated];
|
||||
}
|
||||
|
||||
- (void)updateTransitInfo:(TransitRouteInfo const &)info {
|
||||
if (auto entity = self.entity) {
|
||||
- (void)updateTransitInfo:(TransitRouteInfo const &)info
|
||||
{
|
||||
if (auto entity = self.entity)
|
||||
{
|
||||
entity.timeToTarget = info.m_totalTimeInSec;
|
||||
entity.targetDistance = @(info.m_totalPedestrianDistanceStr.c_str());
|
||||
entity.targetUnits = @(info.m_totalPedestrianUnitsSuffix.c_str());
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
NSString * const kRoutePreviewIPhoneXibName = @"MWMiPhoneRoutePreview";
|
||||
NSString * const kNavigationInfoViewXibName = @"MWMNavigationInfoView";
|
||||
NSString * const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
@@ -40,23 +41,26 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
@implementation MWMNavigationDashboardManager
|
||||
|
||||
+ (MWMNavigationDashboardManager *)sharedManager {
|
||||
+ (MWMNavigationDashboardManager *)sharedManager
|
||||
{
|
||||
return [MWMMapViewControlsManager manager].navigationManager;
|
||||
}
|
||||
|
||||
- (instancetype)initWithParentView:(UIView *)view {
|
||||
- (instancetype)initWithParentView:(UIView *)view
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
_ownerView = view;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (SearchOnMapManager *)searchManager {
|
||||
- (SearchOnMapManager *)searchManager
|
||||
{
|
||||
return [[MapViewController sharedController] searchManager];
|
||||
}
|
||||
|
||||
- (void)loadPreviewWithStatusBoxes {
|
||||
- (void)loadPreviewWithStatusBoxes
|
||||
{
|
||||
[NSBundle.mainBundle loadNibNamed:kRoutePreviewIPhoneXibName owner:self options:nil];
|
||||
auto ownerView = self.ownerView;
|
||||
_baseRoutePreviewStatus.ownerView = ownerView;
|
||||
@@ -65,23 +69,27 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - MWMRoutePreview
|
||||
|
||||
- (void)setRouteBuilderProgress:(CGFloat)progress {
|
||||
- (void)setRouteBuilderProgress:(CGFloat)progress
|
||||
{
|
||||
[self.routePreview router:[MWMRouter type] setProgress:progress / 100.];
|
||||
}
|
||||
|
||||
#pragma mark - MWMNavigationGo
|
||||
|
||||
- (IBAction)routingStartTouchUpInside {
|
||||
- (IBAction)routingStartTouchUpInside
|
||||
{
|
||||
[MWMRouter startRouting];
|
||||
}
|
||||
- (void)updateGoButtonTitle {
|
||||
- (void)updateGoButtonTitle
|
||||
{
|
||||
NSString * title = L(@"p2p_start");
|
||||
|
||||
for (MWMRouteStartButton * button in self.goButtons)
|
||||
[button setTitle:title forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
- (void)onNavigationInfoUpdated {
|
||||
- (void)onNavigationInfoUpdated
|
||||
{
|
||||
auto entity = self.entity;
|
||||
if (!entity.isValid)
|
||||
return;
|
||||
@@ -97,34 +105,38 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - On route updates
|
||||
|
||||
- (void)onRoutePrepare {
|
||||
- (void)onRoutePrepare
|
||||
{
|
||||
self.state = MWMNavigationDashboardStatePrepare;
|
||||
self.routePreview.drivingOptionsState = MWMDrivingOptionsStateNone;
|
||||
}
|
||||
|
||||
- (void)onRoutePlanning {
|
||||
- (void)onRoutePlanning
|
||||
{
|
||||
self.state = MWMNavigationDashboardStatePlanning;
|
||||
self.routePreview.drivingOptionsState = MWMDrivingOptionsStateNone;
|
||||
}
|
||||
|
||||
- (void)onRouteError:(NSString *)error {
|
||||
- (void)onRouteError:(NSString *)error
|
||||
{
|
||||
self.errorMessage = error;
|
||||
self.state = MWMNavigationDashboardStateError;
|
||||
self.routePreview.drivingOptionsState =
|
||||
[MWMRouter hasActiveDrivingOptions] ? MWMDrivingOptionsStateChange : MWMDrivingOptionsStateNone;
|
||||
}
|
||||
|
||||
- (void)onRouteReady:(BOOL)hasWarnings {
|
||||
- (void)onRouteReady:(BOOL)hasWarnings
|
||||
{
|
||||
if (self.state != MWMNavigationDashboardStateNavigation)
|
||||
self.state = MWMNavigationDashboardStateReady;
|
||||
if ([MWMRouter hasActiveDrivingOptions]) {
|
||||
if ([MWMRouter hasActiveDrivingOptions])
|
||||
self.routePreview.drivingOptionsState = MWMDrivingOptionsStateChange;
|
||||
} else {
|
||||
else
|
||||
self.routePreview.drivingOptionsState = hasWarnings ? MWMDrivingOptionsStateDefine : MWMDrivingOptionsStateNone;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onRoutePointsUpdated {
|
||||
- (void)onRoutePointsUpdated
|
||||
{
|
||||
if (self.state == MWMNavigationDashboardStateHidden)
|
||||
self.state = MWMNavigationDashboardStatePrepare;
|
||||
[self.navigationInfoView updateToastView];
|
||||
@@ -132,7 +144,8 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - State changes
|
||||
|
||||
- (void)stateHidden {
|
||||
- (void)stateHidden
|
||||
{
|
||||
self.routePreview = nil;
|
||||
self.navigationInfoView.state = MWMNavigationInfoViewStateHidden;
|
||||
self.navigationInfoView = nil;
|
||||
@@ -143,7 +156,8 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
_transportRoutePreviewStatus = nil;
|
||||
}
|
||||
|
||||
- (void)statePrepare {
|
||||
- (void)statePrepare
|
||||
{
|
||||
self.navigationInfoView.state = MWMNavigationInfoViewStatePrepare;
|
||||
if (self.searchManager.isSearching)
|
||||
[self.navigationInfoView setSearchState:NavigationSearchState::MinimizedSearch animated:YES];
|
||||
@@ -158,13 +172,15 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
[button statePrepare];
|
||||
}
|
||||
|
||||
- (void)statePlanning {
|
||||
- (void)statePlanning
|
||||
{
|
||||
[self statePrepare];
|
||||
[self.routePreview router:[MWMRouter type] setState:MWMCircularProgressStateSpinner];
|
||||
[self setRouteBuilderProgress:0.];
|
||||
}
|
||||
|
||||
- (void)stateError {
|
||||
- (void)stateError
|
||||
{
|
||||
if (_state == MWMNavigationDashboardStateReady)
|
||||
return;
|
||||
|
||||
@@ -177,10 +193,13 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
[button stateError];
|
||||
}
|
||||
|
||||
- (void)stateReady {
|
||||
// TODO: Here assert sometimes fires with _state = MWMNavigationDashboardStateReady, if app was stopped while navigating and then restarted.
|
||||
// Also in ruler mode when new point is added by single tap on the map state MWMNavigationDashboardStatePlanning is skipped and we get _state = MWMNavigationDashboardStateReady.
|
||||
NSAssert(_state == MWMNavigationDashboardStatePlanning || _state == MWMNavigationDashboardStateReady, @"Invalid state change (ready)");
|
||||
- (void)stateReady
|
||||
{
|
||||
// TODO: Here assert sometimes fires with _state = MWMNavigationDashboardStateReady, if app was stopped while
|
||||
// navigating and then restarted. Also in ruler mode when new point is added by single tap on the map state
|
||||
// MWMNavigationDashboardStatePlanning is skipped and we get _state = MWMNavigationDashboardStateReady.
|
||||
NSAssert(_state == MWMNavigationDashboardStatePlanning || _state == MWMNavigationDashboardStateReady,
|
||||
@"Invalid state change (ready)");
|
||||
[self setRouteBuilderProgress:100.];
|
||||
[self updateGoButtonTitle];
|
||||
bool const isTransport = ([MWMRouter type] == MWMRouterTypePublicTransport);
|
||||
@@ -191,23 +210,24 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
[self.baseRoutePreviewStatus showReady];
|
||||
self.goButtonsContainer.hidden = isTransport || isRuler;
|
||||
for (MWMRouteStartButton * button in self.goButtons)
|
||||
{
|
||||
if (isRuler)
|
||||
[button stateHidden];
|
||||
else
|
||||
[button stateReady];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onRouteStart {
|
||||
- (void)onRouteStart
|
||||
{
|
||||
[MWMSearch clear];
|
||||
[self.searchManager close];
|
||||
self.state = MWMNavigationDashboardStateNavigation;
|
||||
}
|
||||
- (void)onRouteStop {
|
||||
- (void)onRouteStop
|
||||
{
|
||||
self.state = MWMNavigationDashboardStateHidden;
|
||||
}
|
||||
- (void)stateNavigation {
|
||||
- (void)stateNavigation
|
||||
{
|
||||
self.routePreview = nil;
|
||||
self.navigationInfoView.state = MWMNavigationInfoViewStateNavigation;
|
||||
self.navigationControlView.isVisible = YES;
|
||||
@@ -219,7 +239,8 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - MWMRoutePreviewStatus
|
||||
|
||||
- (IBAction)showRouteManager {
|
||||
- (IBAction)showRouteManager
|
||||
{
|
||||
auto routeManagerViewModel = [[MWMRouteManagerViewModel alloc] init];
|
||||
auto routeManager = [[MWMRouteManagerViewController alloc] initWithViewModel:routeManagerViewModel];
|
||||
routeManager.modalPresentationStyle = UIModalPresentationCustom;
|
||||
@@ -230,23 +251,27 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
[[MapViewController sharedController] presentViewController:routeManager animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (IBAction)saveRouteAsTrack:(id)sender {
|
||||
- (IBAction)saveRouteAsTrack:(id)sender
|
||||
{
|
||||
[MWMFrameworkHelper saveRouteAsTrack];
|
||||
[self.baseRoutePreviewStatus setRouteSaved:YES];
|
||||
}
|
||||
|
||||
#pragma mark - MWMNavigationControlView
|
||||
|
||||
- (IBAction)ttsButtonAction {
|
||||
- (IBAction)ttsButtonAction
|
||||
{
|
||||
BOOL const isEnabled = [MWMTextToSpeech tts].active;
|
||||
[MWMTextToSpeech tts].active = !isEnabled;
|
||||
}
|
||||
|
||||
- (IBAction)settingsButtonAction {
|
||||
- (IBAction)settingsButtonAction
|
||||
{
|
||||
[[MapViewController sharedController] openSettings];
|
||||
}
|
||||
|
||||
- (IBAction)stopRoutingButtonAction {
|
||||
- (IBAction)stopRoutingButtonAction
|
||||
{
|
||||
[MWMSearch clear];
|
||||
[MWMRouter stopRouting];
|
||||
[self.searchManager close];
|
||||
@@ -254,8 +279,10 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - SearchOnMapManagerObserver
|
||||
|
||||
- (void)searchManagerWithDidChangeState:(SearchOnMapState)state {
|
||||
switch (state) {
|
||||
- (void)searchManagerWithDidChangeState:(SearchOnMapState)state
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SearchOnMapStateClosed:
|
||||
[self.navigationInfoView setSearchState:NavigationSearchState::MinimizedNormal animated:YES];
|
||||
break;
|
||||
@@ -268,39 +295,31 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - Available area
|
||||
|
||||
+ (void)updateNavigationInfoAvailableArea:(CGRect)frame {
|
||||
+ (void)updateNavigationInfoAvailableArea:(CGRect)frame
|
||||
{
|
||||
[[self sharedManager] updateNavigationInfoAvailableArea:frame];
|
||||
}
|
||||
|
||||
- (void)updateNavigationInfoAvailableArea:(CGRect)frame {
|
||||
- (void)updateNavigationInfoAvailableArea:(CGRect)frame
|
||||
{
|
||||
_navigationInfoView.availableArea = frame;
|
||||
}
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setState:(MWMNavigationDashboardState)state {
|
||||
- (void)setState:(MWMNavigationDashboardState)state
|
||||
{
|
||||
if (state == MWMNavigationDashboardStateHidden)
|
||||
[self.searchManager removeObserver:self];
|
||||
else
|
||||
[self.searchManager addObserver:self];
|
||||
switch (state) {
|
||||
case MWMNavigationDashboardStateHidden:
|
||||
[self stateHidden];
|
||||
break;
|
||||
case MWMNavigationDashboardStatePrepare:
|
||||
[self statePrepare];
|
||||
break;
|
||||
case MWMNavigationDashboardStatePlanning:
|
||||
[self statePlanning];
|
||||
break;
|
||||
case MWMNavigationDashboardStateError:
|
||||
[self stateError];
|
||||
break;
|
||||
case MWMNavigationDashboardStateReady:
|
||||
[self stateReady];
|
||||
break;
|
||||
case MWMNavigationDashboardStateNavigation:
|
||||
[self stateNavigation];
|
||||
break;
|
||||
switch (state)
|
||||
{
|
||||
case MWMNavigationDashboardStateHidden: [self stateHidden]; break;
|
||||
case MWMNavigationDashboardStatePrepare: [self statePrepare]; break;
|
||||
case MWMNavigationDashboardStatePlanning: [self statePlanning]; break;
|
||||
case MWMNavigationDashboardStateError: [self stateError]; break;
|
||||
case MWMNavigationDashboardStateReady: [self stateReady]; break;
|
||||
case MWMNavigationDashboardStateNavigation: [self stateNavigation]; break;
|
||||
}
|
||||
_state = state;
|
||||
[[MapViewController sharedController] updateStatusBarStyle];
|
||||
@@ -310,13 +329,15 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
}
|
||||
|
||||
@synthesize routePreview = _routePreview;
|
||||
- (MWMRoutePreview *)routePreview {
|
||||
- (MWMRoutePreview *)routePreview
|
||||
{
|
||||
if (!_routePreview)
|
||||
[self loadPreviewWithStatusBoxes];
|
||||
return _routePreview;
|
||||
}
|
||||
|
||||
- (void)setRoutePreview:(MWMRoutePreview *)routePreview {
|
||||
- (void)setRoutePreview:(MWMRoutePreview *)routePreview
|
||||
{
|
||||
if (routePreview == _routePreview)
|
||||
return;
|
||||
[_routePreview remove];
|
||||
@@ -324,20 +345,24 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
_routePreview.delegate = self;
|
||||
}
|
||||
|
||||
- (MWMBaseRoutePreviewStatus *)baseRoutePreviewStatus {
|
||||
- (MWMBaseRoutePreviewStatus *)baseRoutePreviewStatus
|
||||
{
|
||||
if (!_baseRoutePreviewStatus)
|
||||
[self loadPreviewWithStatusBoxes];
|
||||
return _baseRoutePreviewStatus;
|
||||
}
|
||||
|
||||
- (MWMTransportRoutePreviewStatus *)transportRoutePreviewStatus {
|
||||
- (MWMTransportRoutePreviewStatus *)transportRoutePreviewStatus
|
||||
{
|
||||
if (!_transportRoutePreviewStatus)
|
||||
[self loadPreviewWithStatusBoxes];
|
||||
return _transportRoutePreviewStatus;
|
||||
}
|
||||
|
||||
- (MWMNavigationInfoView *)navigationInfoView {
|
||||
if (!_navigationInfoView) {
|
||||
- (MWMNavigationInfoView *)navigationInfoView
|
||||
{
|
||||
if (!_navigationInfoView)
|
||||
{
|
||||
[NSBundle.mainBundle loadNibNamed:kNavigationInfoViewXibName owner:self options:nil];
|
||||
_navigationInfoView.state = MWMNavigationInfoViewStateHidden;
|
||||
_navigationInfoView.ownerView = self.ownerView;
|
||||
@@ -345,15 +370,18 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
return _navigationInfoView;
|
||||
}
|
||||
|
||||
- (MWMNavigationControlView *)navigationControlView {
|
||||
if (!_navigationControlView) {
|
||||
- (MWMNavigationControlView *)navigationControlView
|
||||
{
|
||||
if (!_navigationControlView)
|
||||
{
|
||||
[NSBundle.mainBundle loadNibNamed:kNavigationControlViewXibName owner:self options:nil];
|
||||
_navigationControlView.ownerView = self.ownerView;
|
||||
}
|
||||
return _navigationControlView;
|
||||
}
|
||||
|
||||
- (MWMNavigationDashboardEntity *)entity {
|
||||
- (MWMNavigationDashboardEntity *)entity
|
||||
{
|
||||
if (!_entity)
|
||||
_entity = [[MWMNavigationDashboardEntity alloc] init];
|
||||
return _entity;
|
||||
@@ -361,7 +389,8 @@ NSString *const kNavigationControlViewXibName = @"NavigationControlView";
|
||||
|
||||
#pragma mark - MWMRoutePreviewDelegate
|
||||
|
||||
- (void)routePreviewDidPressDrivingOptions:(MWMRoutePreview *)routePreview {
|
||||
- (void)routePreviewDidPressDrivingOptions:(MWMRoutePreview *)routePreview
|
||||
{
|
||||
[[MapViewController sharedController] openDrivingOptions];
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ std::map<NavigationSearchState, NSString *> const kSearchButtonRequest{
|
||||
{NavigationSearchState::MinimizedFood, L(@"category_food")},
|
||||
{NavigationSearchState::MinimizedATM, L(@"category_atm")}};
|
||||
|
||||
BOOL defaultOrientation(CGSize const &size) {
|
||||
BOOL defaultOrientation(CGSize const & size)
|
||||
{
|
||||
CGSize const & mapViewSize = [MapViewController sharedController].view.frame.size;
|
||||
CGFloat const minWidth = MIN(mapViewSize.width, mapViewSize.height);
|
||||
return IPAD || (size.height > size.width && size.width >= minWidth);
|
||||
@@ -100,7 +101,8 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
@implementation MWMNavigationInfoView
|
||||
|
||||
- (void)updateToastView {
|
||||
- (void)updateToastView
|
||||
{
|
||||
// -S-F-L -> Start
|
||||
// -S-F+L -> Finish
|
||||
// -S+F-L -> Start
|
||||
@@ -114,7 +116,8 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
BOOL const hasFinish = ([MWMRouter finishPoint] != nil);
|
||||
self.hasLocation = ([MWMLocationManager lastLocation] != nil);
|
||||
|
||||
if (hasStart && hasFinish) {
|
||||
if (hasStart && hasFinish)
|
||||
{
|
||||
[self setToastViewHidden:YES];
|
||||
return;
|
||||
}
|
||||
@@ -123,12 +126,14 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
auto toastView = self.toastView;
|
||||
|
||||
if (hasStart) {
|
||||
if (hasStart)
|
||||
{
|
||||
[toastView configWithIsStart:NO withLocationButton:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasFinish) {
|
||||
if (hasFinish)
|
||||
{
|
||||
[toastView configWithIsStart:YES withLocationButton:self.hasLocation];
|
||||
return;
|
||||
}
|
||||
@@ -139,19 +144,22 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
[toastView configWithIsStart:YES withLocationButton:NO];
|
||||
}
|
||||
|
||||
- (SearchOnMapManager *)searchManager {
|
||||
- (SearchOnMapManager *)searchManager
|
||||
{
|
||||
return [MapViewController sharedController].searchManager;
|
||||
}
|
||||
|
||||
- (IBAction)openSearch {
|
||||
- (IBAction)openSearch
|
||||
{
|
||||
BOOL const isStart = self.toastView.isStart;
|
||||
|
||||
[self.searchManager setRoutingTooltip:
|
||||
isStart ? SearchOnMapRoutingTooltipSearchStart : SearchOnMapRoutingTooltipSearchFinish ];
|
||||
[self.searchManager
|
||||
setRoutingTooltip:isStart ? SearchOnMapRoutingTooltipSearchStart : SearchOnMapRoutingTooltipSearchFinish];
|
||||
[self.searchManager startSearchingWithIsRouting:YES];
|
||||
}
|
||||
|
||||
- (IBAction)addLocationRoutePoint {
|
||||
- (IBAction)addLocationRoutePoint
|
||||
{
|
||||
NSAssert(![MWMRouter startPoint], @"Action button is active while start point is available");
|
||||
NSAssert([MWMLocationManager lastLocation], @"Action button is active while my location is not available");
|
||||
|
||||
@@ -162,18 +170,19 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
#pragma mark - Search
|
||||
|
||||
- (IBAction)searchMainButtonTouchUpInside {
|
||||
switch (self.searchState) {
|
||||
- (IBAction)searchMainButtonTouchUpInside
|
||||
{
|
||||
switch (self.searchState)
|
||||
{
|
||||
case NavigationSearchState::Maximized:
|
||||
[self.searchManager startSearchingWithIsRouting:YES];
|
||||
[self setSearchState:NavigationSearchState::MinimizedNormal animated:YES];
|
||||
break;
|
||||
case NavigationSearchState::MinimizedNormal:
|
||||
if (self.state == MWMNavigationInfoViewStatePrepare) {
|
||||
if (self.state == MWMNavigationInfoViewStatePrepare)
|
||||
[self.searchManager startSearchingWithIsRouting:YES];
|
||||
} else {
|
||||
else
|
||||
[self setSearchState:NavigationSearchState::Maximized animated:YES];
|
||||
}
|
||||
break;
|
||||
case NavigationSearchState::MinimizedSearch:
|
||||
case NavigationSearchState::MinimizedGas:
|
||||
@@ -188,7 +197,8 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)searchButtonTouchUpInside:(MWMButton *)sender {
|
||||
- (IBAction)searchButtonTouchUpInside:(MWMButton *)sender
|
||||
{
|
||||
auto const body = ^(NavigationSearchState state) {
|
||||
NSString * text = [kSearchButtonRequest.at(state) stringByAppendingString:@" "];
|
||||
NSString * locale = [[AppInfo sharedInfo] languageId];
|
||||
@@ -210,21 +220,25 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
body(NavigationSearchState::MinimizedATM);
|
||||
}
|
||||
|
||||
- (IBAction)bookmarksButtonTouchUpInside {
|
||||
- (IBAction)bookmarksButtonTouchUpInside
|
||||
{
|
||||
[[MapViewController sharedController].bookmarksCoordinator open];
|
||||
}
|
||||
|
||||
- (void)collapseSearchOnTimer {
|
||||
- (void)collapseSearchOnTimer
|
||||
{
|
||||
[self setSearchState:NavigationSearchState::MinimizedNormal animated:YES];
|
||||
}
|
||||
|
||||
- (void)layoutSearch {
|
||||
- (void)layoutSearch
|
||||
{
|
||||
BOOL const defaultView = defaultOrientation(self.availableArea.size);
|
||||
CGFloat alpha = 0;
|
||||
CGFloat searchButtonsSideSize = 0;
|
||||
self.searchButtonsViewWidth.constant = 0;
|
||||
self.searchButtonsViewHeight.constant = 0;
|
||||
if (self.searchState == NavigationSearchState::Maximized) {
|
||||
if (self.searchState == NavigationSearchState::Maximized)
|
||||
{
|
||||
alpha = 1;
|
||||
searchButtonsSideSize = kSearchButtonsSideSize;
|
||||
self.searchButtonsViewWidth.constant =
|
||||
@@ -242,31 +256,43 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
#pragma mark - MWMNavigationDashboardManager
|
||||
|
||||
- (void)onNavigationInfoUpdated:(MWMNavigationDashboardEntity *)info {
|
||||
- (void)onNavigationInfoUpdated:(MWMNavigationDashboardEntity *)info
|
||||
{
|
||||
self.navigationInfo = info;
|
||||
if (self.state != MWMNavigationInfoViewStateNavigation)
|
||||
return;
|
||||
if (info.streetName.length != 0) {
|
||||
if (info.streetName.length != 0)
|
||||
{
|
||||
[self setStreetNameVisible:YES];
|
||||
self.streetNameLabel.text = info.streetName;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setStreetNameVisible:NO];
|
||||
}
|
||||
if (info.turnImage) {
|
||||
if (info.turnImage)
|
||||
{
|
||||
[self setTurnsViewVisible:YES];
|
||||
self.nextTurnImageView.image = info.turnImage;
|
||||
|
||||
if (info.roundExitNumber == 0) {
|
||||
if (info.roundExitNumber == 0)
|
||||
{
|
||||
self.roundTurnLabel.hidden = YES;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self.roundTurnLabel.hidden = NO;
|
||||
self.roundTurnLabel.text = @(info.roundExitNumber).stringValue;
|
||||
}
|
||||
|
||||
NSDictionary *turnNumberAttributes =
|
||||
@{NSForegroundColorAttributeName: [UIColor white], NSFontAttributeName: IPAD ? [UIFont bold36] : [UIFont bold28]};
|
||||
NSDictionary *turnLegendAttributes =
|
||||
@{NSForegroundColorAttributeName: [UIColor white], NSFontAttributeName: IPAD ? [UIFont bold24] : [UIFont bold16]};
|
||||
NSDictionary * turnNumberAttributes = @{
|
||||
NSForegroundColorAttributeName: [UIColor white],
|
||||
NSFontAttributeName: IPAD ? [UIFont bold36] : [UIFont bold28]
|
||||
};
|
||||
NSDictionary * turnLegendAttributes = @{
|
||||
NSForegroundColorAttributeName: [UIColor white],
|
||||
NSFontAttributeName: IPAD ? [UIFont bold24] : [UIFont bold16]
|
||||
};
|
||||
|
||||
NSMutableAttributedString * distance = [[NSMutableAttributedString alloc] initWithString:info.distanceToTurn
|
||||
attributes:turnNumberAttributes];
|
||||
@@ -275,13 +301,18 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
attributes:turnLegendAttributes]];
|
||||
|
||||
self.distanceToNextTurnLabel.attributedText = distance;
|
||||
if (info.nextTurnImage) {
|
||||
if (info.nextTurnImage)
|
||||
{
|
||||
self.secondTurnView.hidden = NO;
|
||||
self.secondTurnImageView.image = info.nextTurnImage;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
self.secondTurnView.hidden = YES;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setTurnsViewVisible:NO];
|
||||
}
|
||||
[self setNeedsLayout];
|
||||
@@ -289,7 +320,8 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onLocationUpdate:(CLLocation *)location {
|
||||
- (void)onLocationUpdate:(CLLocation *)location
|
||||
{
|
||||
BOOL const hasLocation = ([MWMLocationManager lastLocation] != nil);
|
||||
if (self.hasLocation != hasLocation)
|
||||
[self updateToastView];
|
||||
@@ -297,33 +329,38 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
#pragma mark - SolidTouchView
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (self.searchState == NavigationSearchState::Maximized)
|
||||
return;
|
||||
[super touchesBegan:touches withEvent:event];
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (self.searchState == NavigationSearchState::Maximized)
|
||||
return;
|
||||
[super touchesMoved:touches withEvent:event];
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (self.searchState == NavigationSearchState::Maximized)
|
||||
[self setSearchState:NavigationSearchState::MinimizedNormal animated:YES];
|
||||
else
|
||||
[super touchesEnded:touches withEvent:event];
|
||||
}
|
||||
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
if (self.searchState == NavigationSearchState::Maximized)
|
||||
[self setSearchState:NavigationSearchState::MinimizedNormal animated:YES];
|
||||
else
|
||||
[super touchesCancelled:touches withEvent:event];
|
||||
}
|
||||
|
||||
- (void)configLayout {
|
||||
- (void)configLayout
|
||||
{
|
||||
UIView * ov = self.superview;
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
@@ -339,11 +376,14 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
}
|
||||
|
||||
// Additional spacing for devices with a small top safe area (such as SE or when the device is in landscape mode).
|
||||
- (CGFloat)additionalStreetNameTopOffset {
|
||||
return MapsAppDelegate.theApp.window.safeAreaInsets.top <= 20 ? 10 : 0;;
|
||||
- (CGFloat)additionalStreetNameTopOffset
|
||||
{
|
||||
return MapsAppDelegate.theApp.window.safeAreaInsets.top <= 20 ? 10 : 0;
|
||||
;
|
||||
}
|
||||
|
||||
- (void)refreshLayout {
|
||||
- (void)refreshLayout
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
|
||||
self.streetNameLabel.numberOfLines = 1;
|
||||
@@ -363,9 +403,8 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
(defaultOrientation(availableArea.size) ? kSearchButtonsViewHeightPortrait
|
||||
: kSearchButtonsViewHeightLandscape) /
|
||||
2;
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (@available(iOS 13.0, *))
|
||||
self.searchButtonsView.layer.cornerCurve = kCACornerCurveContinuous;
|
||||
}
|
||||
self.streetNameTopOffsetConstraint.constant = self.additionalStreetNameTopOffset;
|
||||
}];
|
||||
});
|
||||
@@ -373,45 +412,56 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setAvailableArea:(CGRect)availableArea {
|
||||
- (void)setAvailableArea:(CGRect)availableArea
|
||||
{
|
||||
if (CGRectEqualToRect(_availableArea, availableArea))
|
||||
return;
|
||||
_availableArea = availableArea;
|
||||
[self refreshLayout];
|
||||
}
|
||||
|
||||
- (void)setSearchState:(NavigationSearchState)searchState animated:(BOOL)animated {
|
||||
- (void)setSearchState:(NavigationSearchState)searchState animated:(BOOL)animated
|
||||
{
|
||||
self.searchState = searchState;
|
||||
auto block = ^{
|
||||
[self layoutSearch];
|
||||
[self layoutIfNeeded];
|
||||
};
|
||||
if (animated) {
|
||||
if (animated)
|
||||
{
|
||||
[self layoutIfNeeded];
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:block];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
block();
|
||||
}
|
||||
SEL const collapseSelector = @selector(collapseSearchOnTimer);
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:collapseSelector object:self];
|
||||
if (self.searchState == NavigationSearchState::Maximized) {
|
||||
if (self.searchState == NavigationSearchState::Maximized)
|
||||
{
|
||||
[self.superview bringSubviewToFront:self];
|
||||
[self performSelector:collapseSelector withObject:self afterDelay:kCollapseSearchTimeout];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.superview sendSubviewToBack:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSearchState:(NavigationSearchState)searchState {
|
||||
- (void)setSearchState:(NavigationSearchState)searchState
|
||||
{
|
||||
_searchState = searchState;
|
||||
self.searchMainButton.imageName = kSearchStateButtonImageNames.at(searchState);
|
||||
}
|
||||
|
||||
- (void)setState:(MWMNavigationInfoViewState)state {
|
||||
- (void)setState:(MWMNavigationInfoViewState)state
|
||||
{
|
||||
if (_state == state)
|
||||
return;
|
||||
_state = state;
|
||||
switch (state) {
|
||||
switch (state)
|
||||
{
|
||||
case MWMNavigationInfoViewStateHidden:
|
||||
self.isVisible = NO;
|
||||
[self setToastViewHidden:YES];
|
||||
@@ -433,22 +483,26 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setStreetNameVisible:(BOOL)isVisible {
|
||||
- (void)setStreetNameVisible:(BOOL)isVisible
|
||||
{
|
||||
self.streetNameView.hidden = !isVisible;
|
||||
self.streetNameViewHideOffset.priority = isVisible ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;
|
||||
}
|
||||
|
||||
- (void)setTurnsViewVisible:(BOOL)isVisible {
|
||||
- (void)setTurnsViewVisible:(BOOL)isVisible
|
||||
{
|
||||
self.turnsView.hidden = !isVisible;
|
||||
self.turnsViewHideOffset.priority = isVisible ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;
|
||||
}
|
||||
|
||||
- (void)setIsVisible:(BOOL)isVisible {
|
||||
- (void)setIsVisible:(BOOL)isVisible
|
||||
{
|
||||
if (_isVisible == isVisible)
|
||||
return;
|
||||
_isVisible = isVisible;
|
||||
[self setNeedsLayout];
|
||||
if (isVisible) {
|
||||
if (isVisible)
|
||||
{
|
||||
[self setSearchState:NavigationSearchState::MinimizedNormal animated:NO];
|
||||
self.turnsWidth.constant = IPAD ? kTurnsiPadWidth : kTurnsiPhoneWidth;
|
||||
UIView * sv = self.ownerView;
|
||||
@@ -459,24 +513,21 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
[self configLayout];
|
||||
}
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
animations:^{ [self layoutIfNeeded]; }
|
||||
completion:^(BOOL finished) {
|
||||
if (!isVisible)
|
||||
[self removeFromSuperview];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setToastViewHidden:(BOOL)hidden {
|
||||
- (void)setToastViewHidden:(BOOL)hidden
|
||||
{
|
||||
if (!hidden)
|
||||
self.toastView.hidden = NO;
|
||||
[self setNeedsLayout];
|
||||
self.toastViewHideOffset.priority = (hidden ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow);
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
animations:^{ [self layoutIfNeeded]; }
|
||||
completion:^(BOOL finished) {
|
||||
if (hidden)
|
||||
self.toastView.hidden = YES;
|
||||
@@ -484,7 +535,8 @@ BOOL defaultOrientation(CGSize const &size) {
|
||||
}
|
||||
|
||||
// MARK: Update Theme
|
||||
- (void)applyTheme {
|
||||
- (void)applyTheme
|
||||
{
|
||||
[self setSearchState:_searchState];
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#import "MWMCircularProgress.h"
|
||||
#import "MWMLocationManager.h"
|
||||
#import "MWMRouter.h"
|
||||
#import "SwiftBridge.h"
|
||||
#import "UIButton+Orientation.h"
|
||||
#import "UIImageView+Coloring.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
@@ -42,7 +42,8 @@ static CGFloat const kDrivingOptionsHeight = 48;
|
||||
[self applyContentViewShadow];
|
||||
}
|
||||
|
||||
- (void)applyContentViewShadow {
|
||||
- (void)applyContentViewShadow
|
||||
{
|
||||
self.contentView.layer.shadowOffset = CGSizeZero;
|
||||
self.contentView.layer.shadowRadius = 2.0;
|
||||
self.contentView.layer.shadowOpacity = 0.7;
|
||||
@@ -50,19 +51,19 @@ static CGFloat const kDrivingOptionsHeight = 48;
|
||||
[self resizeShadow];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
[self.vehicle setNeedsLayout];
|
||||
[self resizeShadow];
|
||||
}
|
||||
|
||||
- (void)resizeShadow {
|
||||
- (void)resizeShadow
|
||||
{
|
||||
CGFloat shadowSize = 1.0;
|
||||
CGRect contentFrame = self.contentView.bounds;
|
||||
CGRect shadowFrame = CGRectMake(contentFrame.origin.x - shadowSize,
|
||||
contentFrame.size.height,
|
||||
contentFrame.size.width + (2 * shadowSize),
|
||||
shadowSize);
|
||||
CGRect shadowFrame = CGRectMake(contentFrame.origin.x - shadowSize, contentFrame.size.height,
|
||||
contentFrame.size.width + (2 * shadowSize), shadowSize);
|
||||
self.contentView.layer.shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;
|
||||
}
|
||||
|
||||
@@ -70,29 +71,28 @@ static CGFloat const kDrivingOptionsHeight = 48;
|
||||
{
|
||||
[self addProgress:self.vehicle imageName:@"ic_car" routerType:MWMRouterTypeVehicle];
|
||||
[self addProgress:self.pedestrian imageName:@"ic_pedestrian" routerType:MWMRouterTypePedestrian];
|
||||
[self addProgress:self.publicTransport
|
||||
imageName:@"ic_train"
|
||||
routerType:MWMRouterTypePublicTransport];
|
||||
[self addProgress:self.publicTransport imageName:@"ic_train" routerType:MWMRouterTypePublicTransport];
|
||||
[self addProgress:self.bicycle imageName:@"ic_bike" routerType:MWMRouterTypeBicycle];
|
||||
[self addProgress:self.ruler imageName:@"ic_ruler_route" routerType:MWMRouterTypeRuler];
|
||||
}
|
||||
|
||||
- (void)addProgress:(UIView *)parentView
|
||||
imageName:(NSString *)imageName
|
||||
routerType:(MWMRouterType)routerType
|
||||
- (void)addProgress:(UIView *)parentView imageName:(NSString *)imageName routerType:(MWMRouterType)routerType
|
||||
{
|
||||
MWMCircularProgress * progress = [[MWMCircularProgress alloc] initWithParentView:parentView];
|
||||
MWMCircularProgressStateVec imageStates = @[@(MWMCircularProgressStateNormal),
|
||||
@(MWMCircularProgressStateProgress), @(MWMCircularProgressStateSpinner)];
|
||||
MWMCircularProgressStateVec imageStates =
|
||||
@[@(MWMCircularProgressStateNormal), @(MWMCircularProgressStateProgress), @(MWMCircularProgressStateSpinner)];
|
||||
|
||||
[progress setImageName:imageName forStates:imageStates];
|
||||
[progress setImageName:[imageName stringByAppendingString:@"_selected"] forStates:@[@(MWMCircularProgressStateSelected), @(MWMCircularProgressStateCompleted)]];
|
||||
[progress setImageName:[imageName stringByAppendingString:@"_selected"]
|
||||
forStates:@[@(MWMCircularProgressStateSelected), @(MWMCircularProgressStateCompleted)]];
|
||||
[progress setImageName:@"ic_error" forStates:@[@(MWMCircularProgressStateFailed)]];
|
||||
|
||||
[progress setColoring:MWMButtonColoringWhiteText
|
||||
forStates:@[@(MWMCircularProgressStateFailed), @(MWMCircularProgressStateSelected),
|
||||
@(MWMCircularProgressStateProgress), @(MWMCircularProgressStateSpinner),
|
||||
@(MWMCircularProgressStateCompleted)]];
|
||||
[progress
|
||||
setColoring:MWMButtonColoringWhiteText
|
||||
forStates:@[
|
||||
@(MWMCircularProgressStateFailed), @(MWMCircularProgressStateSelected), @(MWMCircularProgressStateProgress),
|
||||
@(MWMCircularProgressStateSpinner), @(MWMCircularProgressStateCompleted)
|
||||
]];
|
||||
|
||||
[progress setSpinnerBackgroundColor:UIColor.clearColor];
|
||||
[progress setColor:UIColor.whiteColor
|
||||
@@ -125,7 +125,8 @@ static CGFloat const kDrivingOptionsHeight = 48;
|
||||
m_progresses[routerType].progress = progress;
|
||||
}
|
||||
|
||||
- (IBAction)onDrivingOptions:(UIButton *)sender {
|
||||
- (IBAction)onDrivingOptions:(UIButton *)sender
|
||||
{
|
||||
[self.delegate routePreviewDidPressDrivingOptions:self];
|
||||
}
|
||||
|
||||
@@ -158,39 +159,36 @@ static CGFloat const kDrivingOptionsHeight = 48;
|
||||
[superview addSubview:self];
|
||||
[self setupConstraints];
|
||||
self.actualVisibilityValue = YES;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.isVisible = YES;
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ self.isVisible = YES; });
|
||||
}
|
||||
|
||||
- (void)remove {
|
||||
- (void)remove
|
||||
{
|
||||
self.actualVisibilityValue = NO;
|
||||
self.isVisible = NO;
|
||||
}
|
||||
|
||||
- (void)setupConstraints {}
|
||||
- (void)setupConstraints
|
||||
{}
|
||||
|
||||
- (void)setDrivingOptionsState:(MWMDrivingOptionsState)state {
|
||||
- (void)setDrivingOptionsState:(MWMDrivingOptionsState)state
|
||||
{
|
||||
_drivingOptionsState = state;
|
||||
[self layoutIfNeeded];
|
||||
self.drivingOptionHeightConstraint.constant =
|
||||
(state == MWMDrivingOptionsStateNone) ? -kDrivingOptionsHeight : 0;
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^{
|
||||
[self layoutIfNeeded];
|
||||
}];
|
||||
self.drivingOptionHeightConstraint.constant = (state == MWMDrivingOptionsStateNone) ? -kDrivingOptionsHeight : 0;
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration animations:^{ [self layoutIfNeeded]; }];
|
||||
|
||||
if (state == MWMDrivingOptionsStateDefine) {
|
||||
if (state == MWMDrivingOptionsStateDefine)
|
||||
{
|
||||
[self.drivingOptionsButton setImagePadding:0.0];
|
||||
[self.drivingOptionsButton setImage:nil
|
||||
forState:UIControlStateNormal];
|
||||
[self.drivingOptionsButton setTitle:L(@"define_to_avoid_btn").uppercaseString
|
||||
forState:UIControlStateNormal];
|
||||
} else if (state == MWMDrivingOptionsStateChange) {
|
||||
[self.drivingOptionsButton setImage:nil forState:UIControlStateNormal];
|
||||
[self.drivingOptionsButton setTitle:L(@"define_to_avoid_btn").uppercaseString forState:UIControlStateNormal];
|
||||
}
|
||||
else if (state == MWMDrivingOptionsStateChange)
|
||||
{
|
||||
[self.drivingOptionsButton setImagePadding:5.0];
|
||||
[self.drivingOptionsButton setImage:[UIImage imageNamed:@"ic_options_warning"]
|
||||
forState:UIControlStateNormal];
|
||||
[self.drivingOptionsButton setTitle:L(@"change_driving_options_btn").uppercaseString
|
||||
forState:UIControlStateNormal];
|
||||
[self.drivingOptionsButton setImage:[UIImage imageNamed:@"ic_options_warning"] forState:UIControlStateNormal];
|
||||
[self.drivingOptionsButton setTitle:L(@"change_driving_options_btn").uppercaseString forState:UIControlStateNormal];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,14 +196,13 @@ static CGFloat const kDrivingOptionsHeight = 48;
|
||||
|
||||
- (void)setIsVisible:(BOOL)isVisible
|
||||
{
|
||||
if (isVisible != self.actualVisibilityValue) { return; }
|
||||
if (isVisible != self.actualVisibilityValue)
|
||||
return;
|
||||
_isVisible = isVisible;
|
||||
auto sv = self.superview;
|
||||
[sv setNeedsLayout];
|
||||
[UIView animateWithDuration:kDefaultAnimationDuration
|
||||
animations:^{
|
||||
[sv layoutIfNeeded];
|
||||
}
|
||||
animations:^{ [sv layoutIfNeeded]; }
|
||||
completion:^(BOOL finished) {
|
||||
if (!self.isVisible)
|
||||
[self removeFromSuperview];
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#import "EAGLView.h"
|
||||
#import "iosOGLContextFactory.h"
|
||||
#import "MWMMapWidgets.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#import "iosOGLContextFactory.h"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/logging.hpp"
|
||||
@@ -15,8 +14,8 @@
|
||||
#include <CoreApi/Framework.h>
|
||||
|
||||
#ifdef OMIM_METAL_AVAILABLE
|
||||
#import "MetalContextFactory.h"
|
||||
#import <MetalKit/MetalKit.h>
|
||||
#import "MetalContextFactory.h"
|
||||
#endif
|
||||
|
||||
namespace dp
|
||||
@@ -50,12 +49,9 @@ double getExactDPI(double contentScaleFactor)
|
||||
|
||||
switch (UIDevice.currentDevice.userInterfaceIdiom)
|
||||
{
|
||||
case UIUserInterfaceIdiomPhone:
|
||||
return iPhoneDPI * contentScaleFactor;
|
||||
case UIUserInterfaceIdiomPad:
|
||||
return iPadDPI * contentScaleFactor;
|
||||
default:
|
||||
return mDPI * contentScaleFactor;
|
||||
case UIUserInterfaceIdiomPhone: return iPhoneDPI * contentScaleFactor;
|
||||
case UIUserInterfaceIdiomPad: return iPadDPI * contentScaleFactor;
|
||||
default: return mDPI * contentScaleFactor;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@@ -132,13 +128,11 @@ double getExactDPI(double contentScaleFactor)
|
||||
{
|
||||
CAEAGLLayer * layer = (CAEAGLLayer *)self.layer;
|
||||
layer.opaque = YES;
|
||||
layer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking : @NO,
|
||||
kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8};
|
||||
layer.drawableProperties =
|
||||
@{kEAGLDrawablePropertyRetainedBacking: @NO, kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8};
|
||||
}
|
||||
auto & f = GetFramework();
|
||||
f.SetGraphicsContextInitializationHandler([self]() {
|
||||
self.graphicContextInitialized = YES;
|
||||
});
|
||||
f.SetGraphicsContextInitializationHandler([self]() { self.graphicContextInitialized = YES; });
|
||||
}
|
||||
|
||||
- (void)createDrapeEngine
|
||||
@@ -221,12 +215,14 @@ double getExactDPI(double contentScaleFactor)
|
||||
return _widgetsManager;
|
||||
}
|
||||
|
||||
- (void)updateVisualScaleTo:(CGFloat)visualScale {
|
||||
- (void)updateVisualScaleTo:(CGFloat)visualScale
|
||||
{
|
||||
main_visualScale = df::VisualParams::Instance().GetVisualScale();
|
||||
GetFramework().UpdateVisualScale(visualScale);
|
||||
}
|
||||
|
||||
- (void)updateVisualScaleToMain {
|
||||
- (void)updateVisualScaleToMain
|
||||
{
|
||||
GetFramework().UpdateVisualScale(main_visualScale);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,24 +28,25 @@
|
||||
|
||||
#import "FirstSession.h"
|
||||
|
||||
#include <utility> // std::pair
|
||||
#include <sys/xattr.h>
|
||||
#include <utility> // std::pair
|
||||
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <CoreFoundation/CFURL.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#if (TARGET_OS_IPHONE > 0) // Works for all iOS devices, including iPad.
|
||||
#import <UIKit/UIApplication.h>
|
||||
#import <UIKit/UIDevice.h>
|
||||
#import <UIKit/UIScreen.h>
|
||||
#import <UIKit/UIApplication.h>
|
||||
#import <UIKit/UIWebView.h>
|
||||
#endif // TARGET_OS_IPHONE
|
||||
|
||||
#import <sys/socket.h>
|
||||
#import <netinet/in.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#import <netinet/in.h>
|
||||
#import <sys/socket.h>
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
// Key for app unique installation id in standardUserDefaults.
|
||||
NSString * const kAlohalyticsInstallationId = @"AlohalyticsInstallationId";
|
||||
} // namespace
|
||||
@@ -64,38 +65,49 @@ static NSString * gInstallationId = nil;
|
||||
|
||||
@implementation FirstSession
|
||||
|
||||
+ (void)setup:(NSArray *)serverUrls withLaunchOptions:(NSDictionary *)options {
|
||||
+ (void)setup:(NSArray *)serverUrls withLaunchOptions:(NSDictionary *)options
|
||||
{
|
||||
#if (TARGET_OS_IPHONE > 0)
|
||||
NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
|
||||
Class cls = [FirstSession class];
|
||||
[nc addObserver:cls selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
[nc addObserver:cls selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
|
||||
[nc addObserver:cls
|
||||
selector:@selector(applicationDidEnterBackground:)
|
||||
name:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil];
|
||||
[nc addObserver:cls
|
||||
selector:@selector(applicationWillTerminate:)
|
||||
name:UIApplicationWillTerminateNotification
|
||||
object:nil];
|
||||
#endif // TARGET_OS_IPHONE
|
||||
// INIT
|
||||
[self installationId];
|
||||
}
|
||||
#if (TARGET_OS_IPHONE > 0)
|
||||
+ (void)applicationDidEnterBackground:(NSNotification *)notification {
|
||||
if (gIsFirstSession) {
|
||||
+ (void)applicationDidEnterBackground:(NSNotification *)notification
|
||||
{
|
||||
if (gIsFirstSession)
|
||||
gIsFirstSession = NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)applicationWillTerminate:(NSNotification *)notification {
|
||||
+ (void)applicationWillTerminate:(NSNotification *)notification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
#endif // TARGET_OS_IPHONE
|
||||
|
||||
#pragma mark Utility methods
|
||||
|
||||
+ (BOOL)isFirstSession {
|
||||
+ (BOOL)isFirstSession
|
||||
{
|
||||
return [self installationId] != nil && gIsFirstSession;
|
||||
}
|
||||
|
||||
+ (NSDate *)firstLaunchDate {
|
||||
+ (NSDate *)firstLaunchDate
|
||||
{
|
||||
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];
|
||||
NSDate * date = [ud objectForKey:kFirstLaunchDateKey];
|
||||
if (!date) {
|
||||
if (!date)
|
||||
{
|
||||
// Non-standard situation: this method is called before calling setup. Return current date.
|
||||
date = [NSDate date];
|
||||
[ud setObject:date forKey:kFirstLaunchDateKey];
|
||||
@@ -103,42 +115,51 @@ static NSString * gInstallationId = nil;
|
||||
return date;
|
||||
}
|
||||
|
||||
+ (NSInteger)totalSecondsSpentInTheApp {
|
||||
+ (NSInteger)totalSecondsSpentInTheApp
|
||||
{
|
||||
NSInteger seconds = [[NSUserDefaults standardUserDefaults] integerForKey:kTotalSecondsInTheApp];
|
||||
// Take into an account currently active session.
|
||||
if (gSessionStartTime) {
|
||||
if (gSessionStartTime)
|
||||
seconds += static_cast<NSInteger>(-gSessionStartTime.timeIntervalSinceNow);
|
||||
}
|
||||
return seconds;
|
||||
}
|
||||
|
||||
// Internal helper, returns nil for invalid paths.
|
||||
+ (NSDate *)fileCreationDate:(NSString *)fullPath {
|
||||
+ (NSDate *)fileCreationDate:(NSString *)fullPath
|
||||
{
|
||||
NSDictionary * attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil];
|
||||
return attributes ? [attributes objectForKey:NSFileCreationDate] : nil;
|
||||
}
|
||||
|
||||
+ (NSDate *)installDate {
|
||||
return [FirstSession fileCreationDate:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]];
|
||||
+ (NSDate *)installDate
|
||||
{
|
||||
return [FirstSession
|
||||
fileCreationDate:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]];
|
||||
}
|
||||
|
||||
+ (NSDate *)updateDate {
|
||||
+ (NSDate *)updateDate
|
||||
{
|
||||
return [FirstSession fileCreationDate:[[NSBundle mainBundle] resourcePath]];
|
||||
}
|
||||
|
||||
+ (NSDate *)buildDate {
|
||||
+ (NSDate *)buildDate
|
||||
{
|
||||
return [FirstSession fileCreationDate:[[NSBundle mainBundle] executablePath]];
|
||||
}
|
||||
|
||||
+ (NSString *)installationId {
|
||||
if (gInstallationId == nil) {
|
||||
+ (NSString *)installationId
|
||||
{
|
||||
if (gInstallationId == nil)
|
||||
{
|
||||
gIsFirstSession = NO;
|
||||
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];
|
||||
gInstallationId = [ud stringForKey:kAlohalyticsInstallationId];
|
||||
if (gInstallationId == nil) {
|
||||
if (gInstallationId == nil)
|
||||
{
|
||||
CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
|
||||
// All iOS IDs start with I:
|
||||
gInstallationId = [@"I:" stringByAppendingString:(NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid))];
|
||||
gInstallationId =
|
||||
[@"I:" stringByAppendingString:(NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid))];
|
||||
CFRelease(uuid);
|
||||
[ud setValue:gInstallationId forKey:kAlohalyticsInstallationId];
|
||||
gIsFirstSession = YES;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,6 @@
|
||||
#import "NSDate+TimeDistance.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
|
||||
#import <CarPlay/CarPlay.h>
|
||||
#import <CoreSpotlight/CoreSpotlight.h>
|
||||
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
|
||||
@@ -34,7 +33,8 @@
|
||||
// If you have a "missing header error" here, then please run configure.sh script in the root repo
|
||||
// folder.
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
NSString * const kUDLastLaunchDateKey = @"LastLaunchDate";
|
||||
NSString * const kUDSessionsCountKey = @"SessionsCount";
|
||||
NSString * const kUDFirstVersionKey = @"FirstVersion";
|
||||
@@ -45,7 +45,8 @@ NSString *const kBundleVersion = @"BundleVersion";
|
||||
|
||||
/// Adds needed localized strings to C++ code
|
||||
/// @TODO Refactor localization mechanism to make it simpler
|
||||
void InitLocalizedStrings() {
|
||||
void InitLocalizedStrings()
|
||||
{
|
||||
Framework & f = GetFramework();
|
||||
|
||||
f.AddString("core_entrance", L(@"core_entrance").UTF8String);
|
||||
@@ -57,9 +58,7 @@ void InitLocalizedStrings() {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@interface MapsAppDelegate () <MWMStorageObserver,
|
||||
CPApplicationDelegate>
|
||||
@interface MapsAppDelegate () <MWMStorageObserver, CPApplicationDelegate>
|
||||
|
||||
@property(nonatomic) NSInteger standbyCounter;
|
||||
@property(nonatomic) MWMBackgroundFetchScheduler * backgroundFetchScheduler;
|
||||
@@ -68,19 +67,21 @@ void InitLocalizedStrings() {
|
||||
|
||||
@implementation MapsAppDelegate
|
||||
|
||||
+ (MapsAppDelegate *)theApp {
|
||||
+ (MapsAppDelegate *)theApp
|
||||
{
|
||||
return (MapsAppDelegate *)UIApplication.sharedApplication.delegate;
|
||||
}
|
||||
|
||||
- (BOOL)isDrapeEngineCreated {
|
||||
- (BOOL)isDrapeEngineCreated
|
||||
{
|
||||
return self.mapViewController.mapView.drapeEngineCreated;
|
||||
}
|
||||
|
||||
- (void)searchText:(NSString *)searchString {
|
||||
if (!self.isDrapeEngineCreated) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self searchText:searchString];
|
||||
});
|
||||
- (void)searchText:(NSString *)searchString
|
||||
{
|
||||
if (!self.isDrapeEngineCreated)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [self searchText:searchString]; });
|
||||
return;
|
||||
}
|
||||
SearchQuery * query = [[SearchQuery alloc] init:[searchString stringByAppendingString:@" "]
|
||||
@@ -89,7 +90,8 @@ void InitLocalizedStrings() {
|
||||
[[MWMMapViewControlsManager manager] search:query];
|
||||
}
|
||||
|
||||
- (void)commonInit {
|
||||
- (void)commonInit
|
||||
{
|
||||
[HttpThreadImpl setDownloadIndicatorProtocol:self];
|
||||
InitLocalizedStrings();
|
||||
GetFramework().SetupMeasurementSystem();
|
||||
@@ -103,7 +105,8 @@ void InitLocalizedStrings() {
|
||||
[TrackRecordingManager.shared setup];
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSLog(@"application:didFinishLaunchingWithOptions: %@", launchOptions);
|
||||
|
||||
[HttpThreadImpl setDownloadIndicatorProtocol:self];
|
||||
@@ -113,11 +116,10 @@ void InitLocalizedStrings() {
|
||||
|
||||
[self commonInit];
|
||||
|
||||
if ([FirstSession isFirstSession]) {
|
||||
if ([FirstSession isFirstSession])
|
||||
[self firstLaunchSetup];
|
||||
} else {
|
||||
else
|
||||
[self incrementSessionCount];
|
||||
}
|
||||
[self enableTTSForTheFirstTime];
|
||||
|
||||
if (![MapsAppDelegate isTestsEnvironment])
|
||||
@@ -130,13 +132,15 @@ void InitLocalizedStrings() {
|
||||
|
||||
- (void)application:(UIApplication *)application
|
||||
performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
|
||||
completionHandler:(void (^)(BOOL))completionHandler {
|
||||
completionHandler:(void (^)(BOOL))completionHandler
|
||||
{
|
||||
[self.mapViewController performAction:shortcutItem.type];
|
||||
completionHandler(YES);
|
||||
}
|
||||
|
||||
- (void)runBackgroundTasks:(NSArray<BackgroundFetchTask *> * _Nonnull)tasks
|
||||
completionHandler:(void (^_Nullable)(UIBackgroundFetchResult))completionHandler {
|
||||
completionHandler:(void (^_Nullable)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
self.backgroundFetchScheduler = [[MWMBackgroundFetchScheduler alloc] initWithTasks:tasks
|
||||
completionHandler:^(UIBackgroundFetchResult result) {
|
||||
if (completionHandler)
|
||||
@@ -145,16 +149,19 @@ void InitLocalizedStrings() {
|
||||
[self.backgroundFetchScheduler run];
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
[self.mapViewController onTerminate];
|
||||
// Global cleanup
|
||||
DeleteFramework();
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
LOG(LINFO, ("applicationDidEnterBackground - begin"));
|
||||
[DeepLinkHandler.shared reset];
|
||||
if (m_activeDownloadsCounter) {
|
||||
if (m_activeDownloadsCounter)
|
||||
{
|
||||
m_backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
|
||||
[application endBackgroundTask:self->m_backgroundTask];
|
||||
self->m_backgroundTask = UIBackgroundTaskInvalid;
|
||||
@@ -168,16 +175,20 @@ void InitLocalizedStrings() {
|
||||
LOG(LINFO, ("applicationDidEnterBackground - end"));
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
LOG(LINFO, ("applicationWillResignActive - begin"));
|
||||
[self.mapViewController onGetFocus:NO];
|
||||
auto & f = GetFramework();
|
||||
// On some devices we have to free all belong-to-graphics memory
|
||||
// because of new OpenGL driver powered by Metal.
|
||||
if ([AppInfo sharedInfo].openGLDriver == MWMOpenGLDriverMetalPre103) {
|
||||
if ([AppInfo sharedInfo].openGLDriver == MWMOpenGLDriverMetalPre103)
|
||||
{
|
||||
f.SetRenderingDisabled(true);
|
||||
f.OnDestroySurface();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
f.SetRenderingDisabled(false);
|
||||
}
|
||||
[MWMLocationManager applicationWillResignActive];
|
||||
@@ -185,7 +196,8 @@ void InitLocalizedStrings() {
|
||||
LOG(LINFO, ("applicationWillResignActive - end"));
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
LOG(LINFO, ("applicationWillEnterForeground - begin"));
|
||||
if (!GpsTracker::Instance().IsEnabled())
|
||||
return;
|
||||
@@ -198,15 +210,14 @@ void InitLocalizedStrings() {
|
||||
if ([MWMSettings isTrackWarningAlertShown])
|
||||
return;
|
||||
|
||||
[topVc.alertController presentTrackWarningAlertWithCancelBlock:^{
|
||||
GpsTracker::Instance().SetEnabled(false);
|
||||
}];
|
||||
[topVc.alertController presentTrackWarningAlertWithCancelBlock:^{ GpsTracker::Instance().SetEnabled(false); }];
|
||||
|
||||
[MWMSettings setTrackWarningAlertShown:YES];
|
||||
LOG(LINFO, ("applicationWillEnterForeground - end"));
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
LOG(LINFO, ("applicationDidBecomeActive - begin"));
|
||||
|
||||
auto & f = GetFramework();
|
||||
@@ -215,7 +226,8 @@ void InitLocalizedStrings() {
|
||||
f.SetRenderingEnabled();
|
||||
// On some devices we have to free all belong-to-graphics memory
|
||||
// because of new OpenGL driver powered by Metal.
|
||||
if ([AppInfo sharedInfo].openGLDriver == MWMOpenGLDriverMetalPre103) {
|
||||
if ([AppInfo sharedInfo].openGLDriver == MWMOpenGLDriverMetalPre103)
|
||||
{
|
||||
CGSize const objcSize = self.mapViewController.mapView.pixelSize;
|
||||
f.OnRecoverSurface(static_cast<int>(objcSize.width), static_cast<int>(objcSize.height),
|
||||
true /* recreateContextDependentResources */);
|
||||
@@ -227,8 +239,10 @@ void InitLocalizedStrings() {
|
||||
LOG(LINFO, ("applicationDidBecomeActive - end"));
|
||||
}
|
||||
|
||||
// TODO: Drape enabling and iCloud sync are skipped during the test run due to the app crashing in teardown. This is a temporary solution. Drape should be properly disabled instead of merely skipping the enabling process.
|
||||
+ (BOOL)isTestsEnvironment {
|
||||
// TODO: Drape enabling and iCloud sync are skipped during the test run due to the app crashing in teardown. This is a
|
||||
// temporary solution. Drape should be properly disabled instead of merely skipping the enabling process.
|
||||
+ (BOOL)isTestsEnvironment
|
||||
{
|
||||
NSProcessInfo * processInfo = [NSProcessInfo processInfo];
|
||||
NSArray<NSString *> * launchArguments = [processInfo arguments];
|
||||
BOOL isTests = [launchArguments containsObject:@"-IsTests"];
|
||||
@@ -237,16 +251,20 @@ void InitLocalizedStrings() {
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *_Nullable))restorationHandler {
|
||||
if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) {
|
||||
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
|
||||
{
|
||||
if ([userActivity.activityType isEqualToString:CSSearchableItemActionType])
|
||||
{
|
||||
NSString * searchStringKey = userActivity.userInfo[CSSearchableItemActivityIdentifier];
|
||||
NSString * searchString = L(searchStringKey);
|
||||
if (searchString) {
|
||||
if (searchString)
|
||||
{
|
||||
[self searchText:searchString];
|
||||
return YES;
|
||||
}
|
||||
} else if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] &&
|
||||
userActivity.webpageURL != nil) {
|
||||
}
|
||||
else if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] && userActivity.webpageURL != nil)
|
||||
{
|
||||
LOG(LINFO, ("application:continueUserActivity:restorationHandler: %@", userActivity.webpageURL));
|
||||
return [DeepLinkHandler.shared applicationDidReceiveUniversalLink:userActivity.webpageURL];
|
||||
}
|
||||
@@ -254,29 +272,35 @@ void InitLocalizedStrings() {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)disableDownloadIndicator {
|
||||
- (void)disableDownloadIndicator
|
||||
{
|
||||
--m_activeDownloadsCounter;
|
||||
if (m_activeDownloadsCounter <= 0) {
|
||||
if (m_activeDownloadsCounter <= 0)
|
||||
{
|
||||
m_activeDownloadsCounter = 0;
|
||||
if (UIApplication.sharedApplication.applicationState == UIApplicationStateBackground) {
|
||||
if (UIApplication.sharedApplication.applicationState == UIApplicationStateBackground)
|
||||
{
|
||||
[UIApplication.sharedApplication endBackgroundTask:m_backgroundTask];
|
||||
m_backgroundTask = UIBackgroundTaskInvalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enableDownloadIndicator {
|
||||
- (void)enableDownloadIndicator
|
||||
{
|
||||
++m_activeDownloadsCounter;
|
||||
}
|
||||
|
||||
+ (void)customizeAppearanceForNavigationBar:(UINavigationBar *)navigationBar {
|
||||
+ (void)customizeAppearanceForNavigationBar:(UINavigationBar *)navigationBar
|
||||
{
|
||||
auto backImage =
|
||||
[[UIImage imageNamed:@"ic_nav_bar_back_sys"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
|
||||
navigationBar.backIndicatorImage = backImage;
|
||||
navigationBar.backIndicatorTransitionMaskImage = backImage;
|
||||
}
|
||||
|
||||
+ (void)customizeAppearance {
|
||||
+ (void)customizeAppearance
|
||||
{
|
||||
[UIButton appearance].exclusiveTouch = YES;
|
||||
|
||||
[self customizeAppearanceForNavigationBar:[UINavigationBar appearance]];
|
||||
@@ -287,16 +311,19 @@ void InitLocalizedStrings() {
|
||||
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
|
||||
{
|
||||
NSLog(@"application:openURL: %@ options: %@", url, options);
|
||||
return [DeepLinkHandler.shared applicationDidOpenUrl:url];
|
||||
}
|
||||
|
||||
- (void)showMap {
|
||||
- (void)showMap
|
||||
{
|
||||
[(UINavigationController *)self.window.rootViewController popToRootViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)updateApplicationIconBadgeNumber {
|
||||
- (void)updateApplicationIconBadgeNumber
|
||||
{
|
||||
auto const number = [self badgeNumber];
|
||||
|
||||
// Delay init because BottomTabBarViewController.controller is null here.
|
||||
@@ -306,7 +333,8 @@ void InitLocalizedStrings() {
|
||||
});
|
||||
}
|
||||
|
||||
- (NSUInteger)badgeNumber {
|
||||
- (NSUInteger)badgeNumber
|
||||
{
|
||||
auto & s = GetFramework().GetStorage();
|
||||
storage::Storage::UpdateInfo updateInfo{};
|
||||
s.GetUpdateInfo(s.GetRootId(), updateInfo);
|
||||
@@ -315,13 +343,15 @@ void InitLocalizedStrings() {
|
||||
|
||||
- (void)application:(UIApplication *)application
|
||||
handleEventsForBackgroundURLSession:(NSString *)identifier
|
||||
completionHandler:(void (^)())completionHandler {
|
||||
completionHandler:(void (^)())completionHandler
|
||||
{
|
||||
[BackgroundDownloader sharedBackgroundMapDownloader].backgroundCompletionHandler = completionHandler;
|
||||
}
|
||||
|
||||
#pragma mark - MWMStorageObserver
|
||||
|
||||
- (void)processCountryEvent:(NSString *)countryId {
|
||||
- (void)processCountryEvent:(NSString *)countryId
|
||||
{
|
||||
// Dispatch this method after delay since there are too many events for group mwms download.
|
||||
// We do not need to update badge frequently.
|
||||
// Update after 1 second delay (after last country event) is sure enough for app badge.
|
||||
@@ -332,44 +362,49 @@ void InitLocalizedStrings() {
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (MapViewController *)mapViewController {
|
||||
for (id vc in [(UINavigationController *)self.window.rootViewController viewControllers]) {
|
||||
- (MapViewController *)mapViewController
|
||||
{
|
||||
for (id vc in [(UINavigationController *)self.window.rootViewController viewControllers])
|
||||
if ([vc isKindOfClass:[MapViewController class]])
|
||||
return vc;
|
||||
}
|
||||
NSAssert(false, @"Please check the logic");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (MWMCarPlayService *)carplayService {
|
||||
- (MWMCarPlayService *)carplayService
|
||||
{
|
||||
return [MWMCarPlayService shared];
|
||||
}
|
||||
|
||||
#pragma mark - TTS
|
||||
|
||||
- (void)enableTTSForTheFirstTime {
|
||||
- (void)enableTTSForTheFirstTime
|
||||
{
|
||||
if (![MWMTextToSpeech savedLanguage].length)
|
||||
[MWMTextToSpeech setTTSEnabled:YES];
|
||||
}
|
||||
|
||||
#pragma mark - Standby
|
||||
|
||||
- (void)enableStandby {
|
||||
- (void)enableStandby
|
||||
{
|
||||
self.standbyCounter--;
|
||||
}
|
||||
- (void)disableStandby {
|
||||
- (void)disableStandby
|
||||
{
|
||||
self.standbyCounter++;
|
||||
}
|
||||
- (void)setStandbyCounter:(NSInteger)standbyCounter {
|
||||
- (void)setStandbyCounter:(NSInteger)standbyCounter
|
||||
{
|
||||
_standbyCounter = MAX(0, standbyCounter);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[UIApplication sharedApplication].idleTimerDisabled = (self.standbyCounter != 0);
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(),
|
||||
^{ [UIApplication sharedApplication].idleTimerDisabled = (self.standbyCounter != 0); });
|
||||
}
|
||||
|
||||
#pragma mark - Alert logic
|
||||
|
||||
- (void)firstLaunchSetup {
|
||||
- (void)firstLaunchSetup
|
||||
{
|
||||
NSString * currentVersion = [NSBundle.mainBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
|
||||
NSUserDefaults * standartDefaults = NSUserDefaults.standardUserDefaults;
|
||||
[standartDefaults setObject:currentVersion forKey:kUDFirstVersionKey];
|
||||
@@ -377,7 +412,8 @@ void InitLocalizedStrings() {
|
||||
[standartDefaults setObject:NSDate.date forKey:kUDLastLaunchDateKey];
|
||||
}
|
||||
|
||||
- (void)incrementSessionCount {
|
||||
- (void)incrementSessionCount
|
||||
{
|
||||
NSUserDefaults * standartDefaults = NSUserDefaults.standardUserDefaults;
|
||||
NSUInteger sessionCount = [standartDefaults integerForKey:kUDSessionsCountKey];
|
||||
NSUInteger const kMaximumSessionCountForShowingShareAlert = 50;
|
||||
@@ -385,7 +421,8 @@ void InitLocalizedStrings() {
|
||||
return;
|
||||
|
||||
NSDate * lastLaunchDate = [standartDefaults objectForKey:kUDLastLaunchDateKey];
|
||||
if (lastLaunchDate.daysToNow > 0) {
|
||||
if (lastLaunchDate.daysToNow > 0)
|
||||
{
|
||||
sessionCount++;
|
||||
[standartDefaults setInteger:sessionCount forKey:kUDSessionsCountKey];
|
||||
[standartDefaults setObject:NSDate.date forKey:kUDLastLaunchDateKey];
|
||||
@@ -394,7 +431,8 @@ void InitLocalizedStrings() {
|
||||
|
||||
#pragma mark - Rate
|
||||
|
||||
- (BOOL)userIsNew {
|
||||
- (BOOL)userIsNew
|
||||
{
|
||||
NSString * currentVersion = [NSBundle.mainBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
|
||||
NSString * firstVersion = [NSUserDefaults.standardUserDefaults stringForKey:kUDFirstVersionKey];
|
||||
if (!firstVersion.length || firstVersionIsLessThanSecond(firstVersion, currentVersion))
|
||||
@@ -407,13 +445,15 @@ void InitLocalizedStrings() {
|
||||
|
||||
- (void)application:(UIApplication *)application
|
||||
didConnectCarInterfaceController:(CPInterfaceController *)interfaceController
|
||||
toWindow:(CPWindow *)window API_AVAILABLE(ios(12.0)) {
|
||||
toWindow:(CPWindow *)window API_AVAILABLE(ios(12.0))
|
||||
{
|
||||
[self.carplayService setupWithWindow:window interfaceController:interfaceController];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application
|
||||
didDisconnectCarInterfaceController:(CPInterfaceController *)interfaceController
|
||||
fromWindow:(CPWindow *)window API_AVAILABLE(ios(12.0)) {
|
||||
fromWindow:(CPWindow *)window API_AVAILABLE(ios(12.0))
|
||||
{
|
||||
[self.carplayService destroy];
|
||||
}
|
||||
|
||||
|
||||
@@ -26,18 +26,13 @@ private:
|
||||
class UploadMetalContext : public dp::metal::MetalBaseContext
|
||||
{
|
||||
public:
|
||||
explicit UploadMetalContext(id<MTLDevice> device)
|
||||
: dp::metal::MetalBaseContext(device, {}, nullptr)
|
||||
{}
|
||||
explicit UploadMetalContext(id<MTLDevice> device) : dp::metal::MetalBaseContext(device, {}, nullptr) {}
|
||||
|
||||
void Present() override {}
|
||||
void MakeCurrent() override {}
|
||||
void Resize(int w, int h) override {}
|
||||
void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override {}
|
||||
void Init(dp::ApiVersion apiVersion) override
|
||||
{
|
||||
CHECK_EQUAL(apiVersion, dp::ApiVersion::Metal, ());
|
||||
}
|
||||
void Init(dp::ApiVersion apiVersion) override { CHECK_EQUAL(apiVersion, dp::ApiVersion::Metal, ()); }
|
||||
|
||||
void SetClearColor(dp::Color const & color) override {}
|
||||
void Clear(uint32_t clearBits, uint32_t storeBits) override {}
|
||||
@@ -46,8 +41,9 @@ public:
|
||||
void SetDepthTestFunction(dp::TestFunction depthFunction) override {}
|
||||
void SetStencilTestEnabled(bool enabled) override {}
|
||||
void SetStencilFunction(dp::StencilFace face, dp::TestFunction stencilFunction) override {}
|
||||
void SetStencilActions(dp::StencilFace face, dp::StencilAction stencilFailAction,
|
||||
dp::StencilAction depthFailAction, dp::StencilAction passAction) override {}
|
||||
void SetStencilActions(dp::StencilFace face, dp::StencilAction stencilFailAction, dp::StencilAction depthFailAction,
|
||||
dp::StencilAction passAction) override
|
||||
{}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
|
||||
@implementation MWMActivityViewController
|
||||
|
||||
- (instancetype)initWithActivityItem:(id<UIActivityItemSource>)activityItem {
|
||||
- (instancetype)initWithActivityItem:(id<UIActivityItemSource>)activityItem
|
||||
{
|
||||
return [self initWithActivityItems:@[activityItem]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithActivityItems:(NSArray *)activityItems {
|
||||
- (instancetype)initWithActivityItems:(NSArray *)activityItems
|
||||
{
|
||||
self = [super initWithActivityItems:activityItems applicationActivities:nil];
|
||||
if (self)
|
||||
self.excludedActivityTypes = @[
|
||||
@@ -25,14 +27,16 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)shareControllerForMyPosition:(CLLocationCoordinate2D)location {
|
||||
+ (instancetype)shareControllerForMyPosition:(CLLocationCoordinate2D)location
|
||||
{
|
||||
MWMShareActivityItem * item = [[MWMShareActivityItem alloc] initForMyPositionAtLocation:location];
|
||||
MWMActivityViewController * shareVC = [[self alloc] initWithActivityItem:item];
|
||||
shareVC.excludedActivityTypes = [shareVC.excludedActivityTypes arrayByAddingObject:UIActivityTypeAirDrop];
|
||||
return shareVC;
|
||||
}
|
||||
|
||||
+ (instancetype)shareControllerForPlacePage:(PlacePageData *)data {
|
||||
+ (instancetype)shareControllerForPlacePage:(PlacePageData *)data
|
||||
{
|
||||
MWMShareActivityItem * item = [[MWMShareActivityItem alloc] initForPlacePage:data];
|
||||
MWMActivityViewController * shareVC = [[self alloc] initWithActivityItem:item];
|
||||
shareVC.excludedActivityTypes = [shareVC.excludedActivityTypes arrayByAddingObject:UIActivityTypeAirDrop];
|
||||
@@ -41,11 +45,11 @@
|
||||
|
||||
+ (instancetype)shareControllerForURL:(NSURL *)url
|
||||
message:(NSString *)message
|
||||
completionHandler:(UIActivityViewControllerCompletionWithItemsHandler)completionHandler {
|
||||
completionHandler:(UIActivityViewControllerCompletionWithItemsHandler)completionHandler
|
||||
{
|
||||
NSMutableArray * items = [NSMutableArray arrayWithObject:message];
|
||||
if (url) {
|
||||
if (url)
|
||||
[items addObject:url];
|
||||
}
|
||||
|
||||
MWMActivityViewController * shareVC = [[self alloc] initWithActivityItems:items.copy];
|
||||
shareVC.excludedActivityTypes = [shareVC.excludedActivityTypes arrayByAddingObject:UIActivityTypePostToFacebook];
|
||||
@@ -53,7 +57,8 @@
|
||||
return shareVC;
|
||||
}
|
||||
|
||||
- (void)presentInParentViewController:(UIViewController *)parentVC anchorView:(UIView *)anchorView {
|
||||
- (void)presentInParentViewController:(UIViewController *)parentVC anchorView:(UIView *)anchorView
|
||||
{
|
||||
self.ownerViewController = parentVC;
|
||||
self.anchorView = anchorView;
|
||||
self.popoverPresentationController.sourceView = anchorView;
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
[activityType isEqualToString:@"com.facebook.Facebook.ShareExtension"] ||
|
||||
[activityType.lowercaseString rangeOfString:@"facebook"].length)
|
||||
{
|
||||
NSString * url = [NSString stringWithFormat:@"https://comaps.app/fb-editor-v1?lang=%@",
|
||||
@(languages::GetCurrentNorm().c_str())];
|
||||
NSString * url =
|
||||
[NSString stringWithFormat:@"https://comaps.app/fb-editor-v1?lang=%@", @(languages::GetCurrentNorm().c_str())];
|
||||
return [NSURL URLWithString:url];
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
if ([activityType isEqualToString:UIActivityTypePostToTwitter] || [activityType isEqualToString:UIActivityTypeMail])
|
||||
return [NSString stringWithFormat:@"%@ %@", L(@"whatsnew_editor_message_1"), comapsURL];
|
||||
|
||||
return [NSString stringWithFormat:@"%@.\n%@\n%@", L(@"editor_sharing_title"), L(@"whatsnew_editor_message_1"), comapsURL];
|
||||
return [NSString
|
||||
stringWithFormat:@"%@.\n%@\n%@", L(@"editor_sharing_title"), L(@"whatsnew_editor_message_1"), comapsURL];
|
||||
}
|
||||
|
||||
- (NSString *)activityViewController:(UIActivityViewController *)activityViewController
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include <CoreApi/Framework.h>
|
||||
#import <CoreApi/PlacePageData.h>
|
||||
#import <CoreApi/PlacePagePreviewData.h>
|
||||
#import <CoreApi/PlacePageInfoData.h>
|
||||
#import <CoreApi/PlacePagePhone.h>
|
||||
#import <CoreApi/PlacePagePreviewData.h>
|
||||
#import <LinkPresentation/LPLinkMetadata.h>
|
||||
|
||||
NSString * httpGe0Url(NSString * shortUrl)
|
||||
@@ -41,7 +41,8 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initForPlacePage:(PlacePageData *)data {
|
||||
- (instancetype)initForPlacePage:(PlacePageData *)data
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
@@ -56,8 +57,7 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
|
||||
auto const title = ^NSString *(PlacePageData *data)
|
||||
{
|
||||
auto const title = ^NSString *(PlacePageData * data) {
|
||||
if (!data || data.isMyPosition)
|
||||
return L(@"core_my_position");
|
||||
else if (data.previewData.title.length > 0)
|
||||
@@ -70,8 +70,8 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
return @"";
|
||||
};
|
||||
|
||||
ms::LatLon const ll = self.data ? ms::LatLon(self.data.locationCoordinate.latitude,
|
||||
self.data.locationCoordinate.longitude)
|
||||
ms::LatLon const ll = self.data
|
||||
? ms::LatLon(self.data.locationCoordinate.latitude, self.data.locationCoordinate.longitude)
|
||||
: ms::LatLon(self.location.latitude, self.location.longitude);
|
||||
std::string const & s = f.CodeGe0url(ll.m_lat, ll.m_lon, f.GetDrawScale(), title(self.data).UTF8String);
|
||||
|
||||
@@ -104,7 +104,8 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
return [self subjectDefault];
|
||||
}
|
||||
|
||||
- (LPLinkMetadata *)activityViewControllerLinkMetadata:(UIActivityViewController *)activityViewController API_AVAILABLE(ios(13.0))
|
||||
- (LPLinkMetadata *)activityViewControllerLinkMetadata:(UIActivityViewController *)activityViewController
|
||||
API_AVAILABLE(ios(13.0))
|
||||
{
|
||||
LPLinkMetadata * metadata = [[LPLinkMetadata alloc] init];
|
||||
metadata.originalURL = [NSURL URLWithString:httpGe0Url([self url:NO])];
|
||||
@@ -118,9 +119,9 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
- (NSString *)itemForTwitter
|
||||
{
|
||||
NSString * shortUrl = [self url:YES];
|
||||
return [NSString stringWithFormat:@"%@\n%@", httpGe0Url(shortUrl),
|
||||
self.isMyPosition ? L(@"my_position_share_email_subject")
|
||||
: self.data.previewData.title];
|
||||
return [NSString
|
||||
stringWithFormat:@"%@\n%@", httpGe0Url(shortUrl),
|
||||
self.isMyPosition ? L(@"my_position_share_email_subject") : self.data.previewData.title];
|
||||
}
|
||||
|
||||
- (NSString *)itemDefaultWithActivityType:(NSString *)activityType
|
||||
@@ -132,27 +133,21 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
BOOL const hasSubject = [activityType isEqualToString:UIActivityTypeMail];
|
||||
if (hasSubject)
|
||||
return url;
|
||||
return [NSString
|
||||
stringWithFormat:@"%@ %@", L(@"my_position_share_email_subject"), url];
|
||||
return [NSString stringWithFormat:@"%@ %@", L(@"my_position_share_email_subject"), url];
|
||||
}
|
||||
|
||||
NSMutableArray * phones = [NSMutableArray new];
|
||||
[self.data.infoData.phones enumerateObjectsUsingBlock:^(PlacePagePhone * _Nonnull phone, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
[phones addObject:phone.phone];
|
||||
}];
|
||||
[self.data.infoData.phones enumerateObjectsUsingBlock:^(PlacePagePhone * _Nonnull phone, NSUInteger idx,
|
||||
BOOL * _Nonnull stop) { [phones addObject:phone.phone]; }];
|
||||
|
||||
NSMutableString * result = [L(@"sharing_call_action_look") mutableCopy];
|
||||
std::vector<NSString *> strings{self.data.previewData.title,
|
||||
self.data.previewData.subtitle,
|
||||
self.data.previewData.secondarySubtitle,
|
||||
[phones componentsJoinedByString:@"; "],
|
||||
std::vector<NSString *> strings{self.data.previewData.title, self.data.previewData.subtitle,
|
||||
self.data.previewData.secondarySubtitle, [phones componentsJoinedByString:@"; "],
|
||||
url};
|
||||
|
||||
for (auto const & str : strings)
|
||||
{
|
||||
if (str.length)
|
||||
[result appendString:[NSString stringWithFormat:@"\n%@", str]];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -161,8 +156,7 @@ NSString * httpGe0Url(NSString * shortUrl)
|
||||
|
||||
- (NSString *)subjectDefault
|
||||
{
|
||||
return self.isMyPosition ? L(@"my_position_share_email_subject")
|
||||
: L(@"bookmark_share_email_subject");
|
||||
return self.isMyPosition ? L(@"my_position_share_email_subject") : L(@"bookmark_share_email_subject");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
#include "base/assert.hpp"
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
|
||||
BOOL canAutoDownload(storage::CountryId const &countryId) {
|
||||
BOOL canAutoDownload(storage::CountryId const & countryId)
|
||||
{
|
||||
if (![MWMSettings autoDownloadEnabled])
|
||||
return NO;
|
||||
if (GetPlatform().ConnectionStatus() != Platform::EConnectionType::CONNECTION_WIFI)
|
||||
@@ -51,18 +53,21 @@ using namespace storage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMMapDownloadDialog {
|
||||
@implementation MWMMapDownloadDialog
|
||||
{
|
||||
CountryId m_countryId;
|
||||
CountryId m_autoDownloadCountryId;
|
||||
}
|
||||
|
||||
+ (instancetype)dialogForController:(MapViewController *)controller {
|
||||
+ (instancetype)dialogForController:(MapViewController *)controller
|
||||
{
|
||||
MWMMapDownloadDialog * dialog = [NSBundle.mainBundle loadNibNamed:[self className] owner:nil options:nil].firstObject;
|
||||
dialog.controller = controller;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
- (void)configDialog {
|
||||
- (void)configDialog
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
auto const & s = f.GetStorage();
|
||||
auto const & p = f.GetDownloadingPolicy();
|
||||
@@ -70,13 +75,15 @@ using namespace storage;
|
||||
NodeAttrs nodeAttrs;
|
||||
s.GetNodeAttrs(m_countryId, nodeAttrs);
|
||||
|
||||
if (!nodeAttrs.m_present && ![MWMRouter isRoutingActive]) {
|
||||
if (!nodeAttrs.m_present && ![MWMRouter isRoutingActive])
|
||||
{
|
||||
BOOL const isMultiParent = nodeAttrs.m_parentInfo.size() > 1;
|
||||
BOOL const noParrent = (nodeAttrs.m_parentInfo[0].m_id == s.GetRootId());
|
||||
BOOL const hideParent = (noParrent || isMultiParent);
|
||||
self.parentNode.hidden = hideParent;
|
||||
self.nodeTopOffset.priority = hideParent ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow;
|
||||
if (!hideParent) {
|
||||
if (!hideParent)
|
||||
{
|
||||
self.parentNode.text = @(nodeAttrs.m_topmostParentInfo[0].m_localName.c_str());
|
||||
self.parentNode.textColor = [UIColor blackSecondaryText];
|
||||
}
|
||||
@@ -87,18 +94,20 @@ using namespace storage;
|
||||
self.nodeSize.text = formattedSize(nodeAttrs.m_mwmSize);
|
||||
self.nodeSize.font = [UIFont medium14].monospaced;
|
||||
|
||||
switch (nodeAttrs.m_status) {
|
||||
switch (nodeAttrs.m_status)
|
||||
{
|
||||
case NodeStatus::NotDownloaded:
|
||||
case NodeStatus::Partly: {
|
||||
case NodeStatus::Partly:
|
||||
{
|
||||
MapViewController * controller = self.controller;
|
||||
BOOL const isMapVisible = [controller.navigationController.topViewController isEqual:controller];
|
||||
if (isMapVisible && !self.isAutoDownloadCancelled && canAutoDownload(m_countryId)) {
|
||||
if (isMapVisible && !self.isAutoDownloadCancelled && canAutoDownload(m_countryId))
|
||||
{
|
||||
m_autoDownloadCountryId = m_countryId;
|
||||
[[MWMStorage sharedStorage] downloadNode:@(m_countryId.c_str())
|
||||
onSuccess:^{
|
||||
[self showInQueue];
|
||||
}];
|
||||
} else {
|
||||
[[MWMStorage sharedStorage] downloadNode:@(m_countryId.c_str()) onSuccess:^{ [self showInQueue]; }];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_autoDownloadCountryId = kInvalidCountryId;
|
||||
[self showDownloadRequest];
|
||||
}
|
||||
@@ -111,23 +120,20 @@ using namespace storage;
|
||||
nodeAttrs.m_downloadingProgress.m_bytesTotal];
|
||||
break;
|
||||
case NodeStatus::Applying:
|
||||
case NodeStatus::InQueue:
|
||||
[self showInQueue];
|
||||
break;
|
||||
case NodeStatus::InQueue: [self showInQueue]; break;
|
||||
case NodeStatus::Undefined:
|
||||
case NodeStatus::Error:
|
||||
if (p.IsAutoRetryDownloadFailed()) {
|
||||
if (p.IsAutoRetryDownloadFailed())
|
||||
[self showError:nodeAttrs.m_error];
|
||||
} else {
|
||||
else
|
||||
[self showInQueue];
|
||||
}
|
||||
break;
|
||||
case NodeStatus::OnDisk:
|
||||
case NodeStatus::OnDiskOutOfDate:
|
||||
[self removeFromSuperview];
|
||||
break;
|
||||
case NodeStatus::OnDiskOutOfDate: [self removeFromSuperview]; break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
@@ -135,7 +141,8 @@ using namespace storage;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)addToSuperview {
|
||||
- (void)addToSuperview
|
||||
{
|
||||
if (self.superview)
|
||||
return;
|
||||
MapViewController * controller = self.controller;
|
||||
@@ -147,15 +154,16 @@ using namespace storage;
|
||||
[self.centerYAnchor constraintEqualToAnchor:controller.view.centerYAnchor].active = YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)removeFromSuperview {
|
||||
- (void)removeFromSuperview
|
||||
{
|
||||
[[MWMCarPlayService shared] hideNoMapAlert];
|
||||
self.progress.state = MWMCircularProgressStateNormal;
|
||||
[[MWMStorage sharedStorage] removeObserver:self];
|
||||
[super removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)showError:(NodeErrorCode)errorCode {
|
||||
- (void)showError:(NodeErrorCode)errorCode
|
||||
{
|
||||
if (errorCode == NodeErrorCode::NoError)
|
||||
return;
|
||||
self.nodeSize.textColor = [UIColor red];
|
||||
@@ -169,41 +177,39 @@ using namespace storage;
|
||||
[self showInQueue];
|
||||
[[MWMStorage sharedStorage] retryDownloadNode:@(self->m_countryId.c_str())];
|
||||
};
|
||||
auto const cancelBlock = ^{
|
||||
[[MWMStorage sharedStorage] cancelDownloadNode:@(self->m_countryId.c_str())];
|
||||
};
|
||||
switch (errorCode) {
|
||||
case NodeErrorCode::NoError:
|
||||
break;
|
||||
auto const cancelBlock = ^{ [[MWMStorage sharedStorage] cancelDownloadNode:@(self->m_countryId.c_str())]; };
|
||||
switch (errorCode)
|
||||
{
|
||||
case NodeErrorCode::NoError: break;
|
||||
case NodeErrorCode::UnknownError:
|
||||
[avc presentDownloaderInternalErrorAlertWithOkBlock:retryBlock cancelBlock:cancelBlock];
|
||||
break;
|
||||
case NodeErrorCode::OutOfMemFailed:
|
||||
[avc presentDownloaderNotEnoughSpaceAlert];
|
||||
break;
|
||||
case NodeErrorCode::OutOfMemFailed: [avc presentDownloaderNotEnoughSpaceAlert]; break;
|
||||
case NodeErrorCode::NoInetConnection:
|
||||
[avc presentDownloaderNoConnectionAlertWithOkBlock:retryBlock cancelBlock:cancelBlock];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showDownloadRequest {
|
||||
- (void)showDownloadRequest
|
||||
{
|
||||
self.downloadButton.hidden = NO;
|
||||
self.progressWrapper.hidden = YES;
|
||||
[self addToSuperview];
|
||||
}
|
||||
|
||||
- (void)showDownloading:(CGFloat)progress {
|
||||
- (void)showDownloading:(CGFloat)progress
|
||||
{
|
||||
self.nodeSize.textColor = [UIColor blackSecondaryText];
|
||||
self.nodeSize.text =
|
||||
[NSString stringWithFormat:@"%@ %.0f%%", L(@"downloader_downloading"), progress * 100.f];
|
||||
self.nodeSize.text = [NSString stringWithFormat:@"%@ %.0f%%", L(@"downloader_downloading"), progress * 100.f];
|
||||
self.downloadButton.hidden = YES;
|
||||
self.progressWrapper.hidden = NO;
|
||||
self.progress.progress = progress;
|
||||
[self addToSuperview];
|
||||
}
|
||||
|
||||
- (void)showInQueue {
|
||||
- (void)showInQueue
|
||||
{
|
||||
self.nodeSize.textColor = [UIColor blackSecondaryText];
|
||||
self.nodeSize.text = L(@"downloader_queued");
|
||||
self.downloadButton.hidden = YES;
|
||||
@@ -212,7 +218,8 @@ using namespace storage;
|
||||
[self addToSuperview];
|
||||
}
|
||||
|
||||
- (void)processViewportCountryEvent:(CountryId const &)countryId {
|
||||
- (void)processViewportCountryEvent:(CountryId const &)countryId
|
||||
{
|
||||
m_countryId = countryId;
|
||||
if (countryId == kInvalidCountryId)
|
||||
[self removeFromSuperview];
|
||||
@@ -222,7 +229,8 @@ using namespace storage;
|
||||
|
||||
#pragma mark - MWMStorageObserver
|
||||
|
||||
- (void)processCountryEvent:(NSString *)countryId {
|
||||
- (void)processCountryEvent:(NSString *)countryId
|
||||
{
|
||||
if (m_countryId != countryId.UTF8String)
|
||||
return;
|
||||
if (self.superview)
|
||||
@@ -231,20 +239,23 @@ using namespace storage;
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)processCountry:(NSString *)countryId
|
||||
downloadedBytes:(uint64_t)downloadedBytes
|
||||
totalBytes:(uint64_t)totalBytes {
|
||||
- (void)processCountry:(NSString *)countryId downloadedBytes:(uint64_t)downloadedBytes totalBytes:(uint64_t)totalBytes
|
||||
{
|
||||
if (self.superview && m_countryId == countryId.UTF8String)
|
||||
[self showDownloading:(CGFloat)downloadedBytes / totalBytes];
|
||||
}
|
||||
|
||||
#pragma mark - MWMCircularProgressDelegate
|
||||
|
||||
- (void)progressButtonPressed:(nonnull MWMCircularProgress *)progress {
|
||||
if (progress.state == MWMCircularProgressStateFailed) {
|
||||
- (void)progressButtonPressed:(nonnull MWMCircularProgress *)progress
|
||||
{
|
||||
if (progress.state == MWMCircularProgressStateFailed)
|
||||
{
|
||||
[self showInQueue];
|
||||
[[MWMStorage sharedStorage] retryDownloadNode:@(m_countryId.c_str())];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_autoDownloadCountryId == m_countryId)
|
||||
self.isAutoDownloadCancelled = YES;
|
||||
[[MWMStorage sharedStorage] cancelDownloadNode:@(m_countryId.c_str())];
|
||||
@@ -253,22 +264,25 @@ using namespace storage;
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)downloadAction {
|
||||
[[MWMStorage sharedStorage] downloadNode:@(m_countryId.c_str())
|
||||
onSuccess:^{ [self showInQueue]; }];
|
||||
- (IBAction)downloadAction
|
||||
{
|
||||
[[MWMStorage sharedStorage] downloadNode:@(m_countryId.c_str()) onSuccess:^{ [self showInQueue]; }];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (MWMCircularProgress *)progress {
|
||||
if (!_progress) {
|
||||
- (MWMCircularProgress *)progress
|
||||
{
|
||||
if (!_progress)
|
||||
{
|
||||
_progress = [MWMCircularProgress downloaderProgressForParentView:self.progressWrapper];
|
||||
_progress.delegate = self;
|
||||
}
|
||||
return _progress;
|
||||
}
|
||||
|
||||
- (NSMutableArray<NSDate *> *)skipDownloadTimes {
|
||||
- (NSMutableArray<NSDate *> *)skipDownloadTimes
|
||||
{
|
||||
if (!_skipDownloadTimes)
|
||||
_skipDownloadTimes = [@[] mutableCopy];
|
||||
return _skipDownloadTimes;
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
self.visualScale = p.m_visualScale;
|
||||
m_skin.reset(new gui::Skin(gui::ResolveGuiSkinFile("default"), p.m_visualScale));
|
||||
m_skin->Resize(p.m_surfaceWidth, p.m_surfaceHeight);
|
||||
m_skin->ForEach(
|
||||
[&p](gui::EWidget widget, gui::Position const & pos) { p.m_widgetsInitInfo[widget] = pos; });
|
||||
p.m_widgetsInitInfo[gui::WIDGET_SCALE_FPS_LABEL] = gui::Position(m2::PointF(self.visualScale * 10, self.visualScale * 45), dp::LeftTop);
|
||||
m_skin->ForEach([&p](gui::EWidget widget, gui::Position const & pos) { p.m_widgetsInitInfo[widget] = pos; });
|
||||
p.m_widgetsInitInfo[gui::WIDGET_SCALE_FPS_LABEL] =
|
||||
gui::Position(m2::PointF(self.visualScale * 10, self.visualScale * 45), dp::LeftTop);
|
||||
}
|
||||
|
||||
- (void)resize:(CGSize)size
|
||||
@@ -35,7 +35,8 @@
|
||||
if (m_skin != nullptr)
|
||||
m_skin->Resize(size.width, size.height);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if ([MWMCarPlayService shared].isCarplayActivated) {
|
||||
if ([MWMCarPlayService shared].isCarplayActivated)
|
||||
{
|
||||
CGRect bounds = [MapViewController sharedController].mapView.bounds;
|
||||
[self updateLayout:bounds];
|
||||
return;
|
||||
@@ -49,9 +50,8 @@
|
||||
if (CGRectEqualToRect(self.availableArea, frame))
|
||||
return;
|
||||
self.availableArea = frame;
|
||||
if ([MWMCarPlayService shared].isCarplayActivated) {
|
||||
if ([MWMCarPlayService shared].isCarplayActivated)
|
||||
return;
|
||||
}
|
||||
[self updateLayout:frame];
|
||||
}
|
||||
|
||||
@@ -68,12 +68,12 @@
|
||||
auto const vs = self.visualScale;
|
||||
auto const viewHeight = [MapViewController sharedController].mapView.height;
|
||||
auto const viewWidth = [MapViewController sharedController].mapView.width;
|
||||
auto const rulerOffset =
|
||||
m2::PointF(frame.origin.x * vs, (frame.origin.y + frame.size.height - viewHeight) * vs);
|
||||
auto const rulerOffset = m2::PointF(frame.origin.x * vs, (frame.origin.y + frame.size.height - viewHeight) * vs);
|
||||
auto const kCompassAdditionalYOffset = [TrackRecordingManager.shared isActive] ? 50 : 0;
|
||||
auto const compassOffset =
|
||||
m2::PointF((frame.origin.x + frame.size.width - viewWidth) * vs, (frame.origin.y + kCompassAdditionalYOffset) * vs);
|
||||
m_skin->ForEach([&](gui::EWidget w, gui::Position const & pos) {
|
||||
auto const compassOffset = m2::PointF((frame.origin.x + frame.size.width - viewWidth) * vs,
|
||||
(frame.origin.y + kCompassAdditionalYOffset) * vs);
|
||||
m_skin->ForEach([&](gui::EWidget w, gui::Position const & pos)
|
||||
{
|
||||
m2::PointF pivot = pos.m_pixelPivot;
|
||||
switch (w)
|
||||
{
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "base/assert.hpp"
|
||||
#include "base/logging.cpp"
|
||||
|
||||
iosOGLContext::iosOGLContext(CAEAGLLayer * layer, dp::ApiVersion apiVersion,
|
||||
iosOGLContext * contextToShareWith, bool needBuffers)
|
||||
iosOGLContext::iosOGLContext(CAEAGLLayer * layer, dp::ApiVersion apiVersion, iosOGLContext * contextToShareWith,
|
||||
bool needBuffers)
|
||||
: m_apiVersion(apiVersion)
|
||||
, m_layer(layer)
|
||||
, m_nativeContext(NULL)
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
size_t constexpr kGLThreadsCount = 2;
|
||||
|
||||
iosOGLContextFactory::iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion,
|
||||
bool presentAvailable)
|
||||
iosOGLContextFactory::iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion, bool presentAvailable)
|
||||
: m_layer(layer)
|
||||
, m_apiVersion(apiVersion)
|
||||
, m_drawContext(nullptr)
|
||||
|
||||
@@ -5,13 +5,16 @@
|
||||
|
||||
@implementation DeepLinkRouteStrategyAdapter
|
||||
|
||||
- (instancetype)init:(NSURL *)url {
|
||||
- (instancetype)init:(NSURL *)url
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
auto const parsedData = GetFramework().GetParsedRoutingData();
|
||||
auto const points = parsedData.m_points;
|
||||
|
||||
if (points.size() == 2) {
|
||||
if (points.size() == 2)
|
||||
{
|
||||
_p1 = [[MWMRoutePoint alloc] initWithURLSchemeRoutePoint:points.front()
|
||||
type:MWMRoutePointTypeStart
|
||||
intermediateIndex:0];
|
||||
@@ -19,7 +22,9 @@
|
||||
type:MWMRoutePointTypeFinish
|
||||
intermediateIndex:0];
|
||||
_type = routerType(parsedData.m_type);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,45 +2,37 @@
|
||||
#import <CoreApi/AppInfo.h>
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "editor/osm_editor.hpp"
|
||||
|
||||
@implementation MWMEditorHelper
|
||||
|
||||
+ (void)uploadEdits:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
if (!Profile.isExisting ||
|
||||
Platform::EConnectionType::CONNECTION_NONE == Platform::ConnectionStatus())
|
||||
if (!Profile.isExisting || Platform::EConnectionType::CONNECTION_NONE == Platform::ConnectionStatus())
|
||||
{
|
||||
completionHandler(UIBackgroundFetchResultFailed);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const lambda = [completionHandler](osm::Editor::UploadResult result) {
|
||||
auto const lambda = [completionHandler](osm::Editor::UploadResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case osm::Editor::UploadResult::Success:
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
break;
|
||||
case osm::Editor::UploadResult::Error:
|
||||
completionHandler(UIBackgroundFetchResultFailed);
|
||||
break;
|
||||
case osm::Editor::UploadResult::NothingToUpload:
|
||||
completionHandler(UIBackgroundFetchResultNoData);
|
||||
break;
|
||||
case osm::Editor::UploadResult::Success: completionHandler(UIBackgroundFetchResultNewData); break;
|
||||
case osm::Editor::UploadResult::Error: completionHandler(UIBackgroundFetchResultFailed); break;
|
||||
case osm::Editor::UploadResult::NothingToUpload: completionHandler(UIBackgroundFetchResultNoData); break;
|
||||
}
|
||||
};
|
||||
|
||||
NSString * authorizationToken = Profile.authorizationToken;
|
||||
if (authorizationToken == nil) {
|
||||
if (authorizationToken == nil)
|
||||
authorizationToken = @"";
|
||||
}
|
||||
std::string const oauthToken = std::string([authorizationToken UTF8String]);
|
||||
osm::Editor::Instance().UploadChanges(
|
||||
oauthToken,
|
||||
{{"created_by",
|
||||
std::string("CoMaps " OMIM_OS_NAME " ") + AppInfo.sharedInfo.bundleVersion.UTF8String},
|
||||
{{"created_by", std::string("CoMaps " OMIM_OS_NAME " ") + AppInfo.sharedInfo.bundleVersion.UTF8String},
|
||||
{"bundle_id", NSBundle.mainBundle.bundleIdentifier.UTF8String}},
|
||||
lambda);
|
||||
}
|
||||
|
||||
@@ -22,10 +22,8 @@ void loopWrappers(Observers * observers, TLoopBlock block)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
for (Observer observer in observers)
|
||||
{
|
||||
if (observer)
|
||||
block(observer);
|
||||
}
|
||||
});
|
||||
}
|
||||
} // namespace
|
||||
@@ -43,9 +41,7 @@ void loopWrappers(Observers * observers, TLoopBlock block)
|
||||
{
|
||||
static MWMFrameworkListener * listener;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
listener = [[super alloc] initListener];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ listener = [[super alloc] initListener]; });
|
||||
return listener;
|
||||
}
|
||||
|
||||
@@ -91,19 +87,21 @@ void loopWrappers(Observers * observers, TLoopBlock block)
|
||||
using namespace storage;
|
||||
Observers * observers = self.routeBuildingObservers;
|
||||
auto & rm = GetFramework().GetRoutingManager();
|
||||
rm.SetRouteBuildingListener(
|
||||
[observers](RouterResultCode code, CountriesSet const & absentCountries) {
|
||||
loopWrappers(observers, [code, absentCountries](TRouteBuildingObserver observer) {
|
||||
[observer processRouteBuilderEvent:code countries:absentCountries];
|
||||
rm.SetRouteBuildingListener([observers](RouterResultCode code, CountriesSet const & absentCountries)
|
||||
{
|
||||
loopWrappers(observers, [code, absentCountries](TRouteBuildingObserver observer)
|
||||
{ [observer processRouteBuilderEvent:code countries:absentCountries]; });
|
||||
});
|
||||
});
|
||||
rm.SetRouteProgressListener([observers](float progress) {
|
||||
loopWrappers(observers, [progress](TRouteBuildingObserver observer) {
|
||||
rm.SetRouteProgressListener([observers](float progress)
|
||||
{
|
||||
loopWrappers(observers, [progress](TRouteBuildingObserver observer)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(processRouteBuilderProgress:)])
|
||||
[observer processRouteBuilderProgress:progress];
|
||||
});
|
||||
});
|
||||
rm.SetRouteRecommendationListener([observers](RoutingManager::Recommendation recommendation) {
|
||||
rm.SetRouteRecommendationListener([observers](RoutingManager::Recommendation recommendation)
|
||||
{
|
||||
MWMRouterRecommendation rec;
|
||||
switch (recommendation)
|
||||
{
|
||||
@@ -111,18 +109,22 @@ void loopWrappers(Observers * observers, TLoopBlock block)
|
||||
rec = MWMRouterRecommendationRebuildAfterPointsLoading;
|
||||
break;
|
||||
}
|
||||
loopWrappers(observers, [rec](TRouteBuildingObserver observer) {
|
||||
loopWrappers(observers, [rec](TRouteBuildingObserver observer)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(processRouteRecommendation:)])
|
||||
[observer processRouteRecommendation:rec];
|
||||
});
|
||||
});
|
||||
rm.SetRouteSpeedCamShowListener([observers](m2::PointD const & point, double cameraSpeedKmPH) {
|
||||
loopWrappers(observers, [cameraSpeedKmPH](TRouteBuildingObserver observer) {
|
||||
rm.SetRouteSpeedCamShowListener([observers](m2::PointD const & point, double cameraSpeedKmPH)
|
||||
{
|
||||
loopWrappers(observers, [cameraSpeedKmPH](TRouteBuildingObserver observer)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(speedCameraShowedUpOnRoute:)])
|
||||
[observer speedCameraShowedUpOnRoute:cameraSpeedKmPH];
|
||||
});
|
||||
});
|
||||
rm.SetRouteSpeedCamsClearListener([observers]() {
|
||||
rm.SetRouteSpeedCamsClearListener([observers]()
|
||||
{
|
||||
loopWrappers(observers, ^(TRouteBuildingObserver observer) {
|
||||
if ([observer respondsToSelector:@selector(speedCameraLeftVisibleArea)])
|
||||
[observer speedCameraLeftVisibleArea];
|
||||
@@ -136,20 +138,18 @@ void loopWrappers(Observers * observers, TLoopBlock block)
|
||||
{
|
||||
Observers * observers = self.drapeObservers;
|
||||
auto & f = GetFramework();
|
||||
f.SetCurrentCountryChangedListener([observers](CountryId const & countryId) {
|
||||
for (TDrapeObserver observer in observers)
|
||||
f.SetCurrentCountryChangedListener([observers](CountryId const & countryId)
|
||||
{
|
||||
for (TDrapeObserver observer in observers)
|
||||
if ([observer respondsToSelector:@selector(processViewportCountryEvent:)])
|
||||
[observer processViewportCountryEvent:countryId];
|
||||
}
|
||||
});
|
||||
|
||||
f.SetViewportListener([observers](ScreenBase const & screen) {
|
||||
for (TDrapeObserver observer in observers)
|
||||
f.SetViewportListener([observers](ScreenBase const & screen)
|
||||
{
|
||||
for (TDrapeObserver observer in observers)
|
||||
if ([observer respondsToSelector:@selector(processViewportChangedEvent)])
|
||||
[observer processViewportChangedEvent];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#import "MWMRoutingManager.h"
|
||||
#import "MWMLocationManager.h"
|
||||
#import "MWMLocationObserver.h"
|
||||
#import "MWMCoreRouterType.h"
|
||||
#import "MWMCoreUnits.h"
|
||||
#import "MWMFrameworkListener.h"
|
||||
#import "MWMFrameworkObservers.h"
|
||||
#import "MWMCoreRouterType.h"
|
||||
#import "MWMLocationManager.h"
|
||||
#import "MWMLocationObserver.h"
|
||||
#import "MWMRoutePoint+CPP.h"
|
||||
#import "MWMCoreUnits.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include <CoreApi/Framework.h>
|
||||
@@ -17,18 +17,19 @@
|
||||
|
||||
@implementation MWMRoutingManager
|
||||
|
||||
+ (MWMRoutingManager *)routingManager {
|
||||
+ (MWMRoutingManager *)routingManager
|
||||
{
|
||||
static MWMRoutingManager * routingManager;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
routingManager = [[self alloc] initManager];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ routingManager = [[self alloc] initManager]; });
|
||||
return routingManager;
|
||||
}
|
||||
|
||||
- (instancetype)initManager {
|
||||
- (instancetype)initManager
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
self.listeners = [NSHashTable<id<MWMRoutingManagerListener>> weakObjectsHashTable];
|
||||
[MWMFrameworkListener addObserver:self];
|
||||
[MWMLocationManager addObserver:self];
|
||||
@@ -36,15 +37,18 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (RoutingManager &)rm {
|
||||
- (RoutingManager &)rm
|
||||
{
|
||||
return GetFramework().GetRoutingManager();
|
||||
}
|
||||
|
||||
- (routing::SpeedCameraManager &)scm {
|
||||
- (routing::SpeedCameraManager &)scm
|
||||
{
|
||||
return self.rm.GetSpeedCamManager();
|
||||
}
|
||||
|
||||
- (MWMRoutePoint *)startPoint {
|
||||
- (MWMRoutePoint *)startPoint
|
||||
{
|
||||
auto const routePoints = self.rm.GetRoutePoints();
|
||||
if (routePoints.empty())
|
||||
return nil;
|
||||
@@ -54,7 +58,8 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (MWMRoutePoint *)endPoint {
|
||||
- (MWMRoutePoint *)endPoint
|
||||
{
|
||||
auto const routePoints = self.rm.GetRoutePoints();
|
||||
if (routePoints.empty())
|
||||
return nil;
|
||||
@@ -64,19 +69,23 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)isOnRoute {
|
||||
- (BOOL)isOnRoute
|
||||
{
|
||||
return self.rm.IsRoutingFollowing();
|
||||
}
|
||||
|
||||
- (BOOL)isRoutingActive {
|
||||
- (BOOL)isRoutingActive
|
||||
{
|
||||
return self.rm.IsRoutingActive();
|
||||
}
|
||||
|
||||
- (BOOL)isRouteFinished {
|
||||
- (BOOL)isRouteFinished
|
||||
{
|
||||
return self.rm.IsRouteFinished();
|
||||
}
|
||||
|
||||
- (MWMRouteInfo *)routeInfo {
|
||||
- (MWMRouteInfo *)routeInfo
|
||||
{
|
||||
if (!self.isRoutingActive)
|
||||
return nil;
|
||||
routing::FollowingInfo info;
|
||||
@@ -90,11 +99,13 @@
|
||||
NSInteger roundExitNumber = 0;
|
||||
if (info.m_turn == routing::turns::CarDirection::EnterRoundAbout ||
|
||||
info.m_turn == routing::turns::CarDirection::StayOnRoundAbout ||
|
||||
info.m_turn == routing::turns::CarDirection::LeaveRoundAbout) {
|
||||
info.m_turn == routing::turns::CarDirection::LeaveRoundAbout)
|
||||
{
|
||||
roundExitNumber = info.m_exitNum;
|
||||
}
|
||||
|
||||
MWMRouteInfo *objCInfo = [[MWMRouteInfo alloc] initWithTimeToTarget:info.m_time
|
||||
MWMRouteInfo * objCInfo =
|
||||
[[MWMRouteInfo alloc] initWithTimeToTarget:info.m_time
|
||||
targetDistance:info.m_distToTarget.GetDistance()
|
||||
targetUnitsIndex:static_cast<UInt8>(info.m_distToTarget.GetUnits())
|
||||
distanceToTurn:info.m_distToTurn.GetDistance()
|
||||
@@ -108,111 +119,119 @@
|
||||
return objCInfo;
|
||||
}
|
||||
|
||||
- (MWMRouterType)type {
|
||||
- (MWMRouterType)type
|
||||
{
|
||||
return routerType(self.rm.GetRouter());
|
||||
}
|
||||
|
||||
- (void)addListener:(id<MWMRoutingManagerListener>)listener {
|
||||
- (void)addListener:(id<MWMRoutingManagerListener>)listener
|
||||
{
|
||||
[self.listeners addObject:listener];
|
||||
}
|
||||
|
||||
- (void)removeListener:(id<MWMRoutingManagerListener>)listener {
|
||||
- (void)removeListener:(id<MWMRoutingManagerListener>)listener
|
||||
{
|
||||
[self.listeners removeObject:listener];
|
||||
}
|
||||
|
||||
- (void)stopRoutingAndRemoveRoutePoints:(BOOL)flag {
|
||||
- (void)stopRoutingAndRemoveRoutePoints:(BOOL)flag
|
||||
{
|
||||
self.rm.CloseRouting(flag);
|
||||
}
|
||||
|
||||
- (void)deleteSavedRoutePoints {
|
||||
- (void)deleteSavedRoutePoints
|
||||
{
|
||||
self.rm.DeleteSavedRoutePoints();
|
||||
}
|
||||
|
||||
- (void)applyRouterType:(MWMRouterType)type {
|
||||
- (void)applyRouterType:(MWMRouterType)type
|
||||
{
|
||||
self.rm.SetRouter(coreRouterType(type));
|
||||
}
|
||||
|
||||
- (void)addRoutePoint:(MWMRoutePoint *)point {
|
||||
- (void)addRoutePoint:(MWMRoutePoint *)point
|
||||
{
|
||||
RouteMarkData startPt = point.routeMarkData;
|
||||
self.rm.AddRoutePoint(std::move(startPt));
|
||||
}
|
||||
|
||||
- (void)saveRoute {
|
||||
- (void)saveRoute
|
||||
{
|
||||
self.rm.SaveRoutePoints();
|
||||
}
|
||||
|
||||
- (void)buildRouteWithDidFailError:(NSError * __autoreleasing __nullable *)errorPtr {
|
||||
- (void)buildRouteWithDidFailError:(NSError * __autoreleasing __nullable *)errorPtr
|
||||
{
|
||||
auto const & points = self.rm.GetRoutePoints();
|
||||
auto const pointsCount = points.size();
|
||||
|
||||
if (pointsCount > 1) {
|
||||
if (pointsCount > 1)
|
||||
{
|
||||
self.rm.BuildRoute();
|
||||
} else {
|
||||
if (errorPtr) {
|
||||
if (pointsCount == 0) {
|
||||
}
|
||||
else if (errorPtr)
|
||||
{
|
||||
if (pointsCount == 0)
|
||||
{
|
||||
*errorPtr = [NSError errorWithDomain:@"comaps.app.routing"
|
||||
code:MWMRouterResultCodeStartPointNotFound
|
||||
userInfo:nil];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const & routePoint = points.front();
|
||||
MWMRouterResultCode code;
|
||||
if (routePoint.m_pointType == RouteMarkType::Start) {
|
||||
if (routePoint.m_pointType == RouteMarkType::Start)
|
||||
code = MWMRouterResultCodeEndPointNotFound;
|
||||
} else {
|
||||
else
|
||||
code = MWMRouterResultCodeStartPointNotFound;
|
||||
}
|
||||
*errorPtr = [NSError errorWithDomain:@"comaps.app.routing"
|
||||
code:code
|
||||
userInfo:nil];
|
||||
}
|
||||
*errorPtr = [NSError errorWithDomain:@"comaps.app.routing" code:code userInfo:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startRoute {
|
||||
- (void)startRoute
|
||||
{
|
||||
[self saveRoute];
|
||||
self.rm.FollowRoute();
|
||||
}
|
||||
|
||||
- (MWMSpeedCameraManagerMode)speedCameraMode {
|
||||
- (MWMSpeedCameraManagerMode)speedCameraMode
|
||||
{
|
||||
auto const mode = self.scm.GetMode();
|
||||
switch (mode) {
|
||||
case routing::SpeedCameraManagerMode::Auto:
|
||||
return MWMSpeedCameraManagerModeAuto;
|
||||
case routing::SpeedCameraManagerMode::Always:
|
||||
return MWMSpeedCameraManagerModeAlways;
|
||||
default:
|
||||
return MWMSpeedCameraManagerModeNever;
|
||||
switch (mode)
|
||||
{
|
||||
case routing::SpeedCameraManagerMode::Auto: return MWMSpeedCameraManagerModeAuto;
|
||||
case routing::SpeedCameraManagerMode::Always: return MWMSpeedCameraManagerModeAlways;
|
||||
default: return MWMSpeedCameraManagerModeNever;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSpeedCameraMode:(MWMSpeedCameraManagerMode)mode {
|
||||
switch (mode) {
|
||||
case MWMSpeedCameraManagerModeAuto:
|
||||
self.scm.SetMode(routing::SpeedCameraManagerMode::Auto);
|
||||
break;
|
||||
case MWMSpeedCameraManagerModeAlways:
|
||||
self.scm.SetMode(routing::SpeedCameraManagerMode::Always);
|
||||
break;
|
||||
default:
|
||||
self.scm.SetMode(routing::SpeedCameraManagerMode::Never);
|
||||
- (void)setSpeedCameraMode:(MWMSpeedCameraManagerMode)mode
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case MWMSpeedCameraManagerModeAuto: self.scm.SetMode(routing::SpeedCameraManagerMode::Auto); break;
|
||||
case MWMSpeedCameraManagerModeAlways: self.scm.SetMode(routing::SpeedCameraManagerMode::Always); break;
|
||||
default: self.scm.SetMode(routing::SpeedCameraManagerMode::Never);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setOnNewTurnCallback:(MWMVoidBlock)callback {
|
||||
self.rm.RoutingSession().SetOnNewTurnCallback([callback] {
|
||||
callback();
|
||||
});
|
||||
- (void)setOnNewTurnCallback:(MWMVoidBlock)callback
|
||||
{
|
||||
self.rm.RoutingSession().SetOnNewTurnCallback([callback] { callback(); });
|
||||
}
|
||||
|
||||
- (void)resetOnNewTurnCallback {
|
||||
- (void)resetOnNewTurnCallback
|
||||
{
|
||||
self.rm.RoutingSession().SetOnNewTurnCallback(nullptr);
|
||||
}
|
||||
|
||||
#pragma mark - MWMFrameworkRouteBuilderObserver implementation
|
||||
|
||||
- (void)processRouteBuilderEvent:(routing::RouterResultCode)code
|
||||
countries:(const storage::CountriesSet &)absentCountries {
|
||||
countries:(const storage::CountriesSet &)absentCountries
|
||||
{
|
||||
NSArray<id<MWMRoutingManagerListener>> * objects = self.listeners.allObjects;
|
||||
MWMRouterResultCode objCCode = MWMRouterResultCode(code);
|
||||
NSMutableArray<NSString *> * objCAbsentCountries = [NSMutableArray new];
|
||||
@@ -220,51 +239,55 @@
|
||||
id nsstr = [NSString stringWithUTF8String:str.c_str()];
|
||||
[objCAbsentCountries addObject:nsstr];
|
||||
});
|
||||
for (id<MWMRoutingManagerListener> object in objects) {
|
||||
[object processRouteBuilderEventWithCode:objCCode
|
||||
countries:objCAbsentCountries];
|
||||
}
|
||||
for (id<MWMRoutingManagerListener> object in objects)
|
||||
[object processRouteBuilderEventWithCode:objCCode countries:objCAbsentCountries];
|
||||
}
|
||||
|
||||
- (void)speedCameraShowedUpOnRoute:(double)speedLimit {
|
||||
- (void)speedCameraShowedUpOnRoute:(double)speedLimit
|
||||
{
|
||||
NSArray<id<MWMRoutingManagerListener>> * objects = self.listeners.allObjects;
|
||||
for (id<MWMRoutingManagerListener> object in objects) {
|
||||
if (speedLimit == routing::SpeedCameraOnRoute::kNoSpeedInfo) {
|
||||
for (id<MWMRoutingManagerListener> object in objects)
|
||||
{
|
||||
if (speedLimit == routing::SpeedCameraOnRoute::kNoSpeedInfo)
|
||||
{
|
||||
[object updateCameraInfo:YES speedLimitMps:-1];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const metersPerSecond = measurement_utils::KmphToMps(speedLimit);
|
||||
[object updateCameraInfo:YES speedLimitMps:metersPerSecond];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)speedCameraLeftVisibleArea {
|
||||
- (void)speedCameraLeftVisibleArea
|
||||
{
|
||||
NSArray<id<MWMRoutingManagerListener>> * objects = self.listeners.allObjects;
|
||||
for (id<MWMRoutingManagerListener> object in objects) {
|
||||
for (id<MWMRoutingManagerListener> object in objects)
|
||||
[object updateCameraInfo:NO speedLimitMps:-1];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - MWMLocationObserver implementation
|
||||
|
||||
- (void)onLocationUpdate:(CLLocation *)location {
|
||||
- (void)onLocationUpdate:(CLLocation *)location
|
||||
{
|
||||
NSMutableArray<NSString *> * turnNotifications = [NSMutableArray array];
|
||||
std::vector<std::string> notifications;
|
||||
auto announceStreets = [NSUserDefaults.standardUserDefaults boolForKey:@"UserDefaultsNeedToEnableStreetNamesTTS"];
|
||||
self.rm.GenerateNotifications(notifications, announceStreets);
|
||||
for (auto const & text : notifications) {
|
||||
for (auto const & text : notifications)
|
||||
[turnNotifications addObject:@(text.c_str())];
|
||||
}
|
||||
NSArray<id<MWMRoutingManagerListener>> * objects = self.listeners.allObjects;
|
||||
for (id<MWMRoutingManagerListener> object in objects) {
|
||||
for (id<MWMRoutingManagerListener> object in objects)
|
||||
[object didLocationUpdate:turnNotifications];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)turnImageName:(routing::turns::CarDirection)turn isPrimary:(BOOL)isPrimary {
|
||||
- (NSString *)turnImageName:(routing::turns::CarDirection)turn isPrimary:(BOOL)isPrimary
|
||||
{
|
||||
using namespace routing::turns;
|
||||
NSString * imageName = nil;
|
||||
switch (turn) {
|
||||
switch (turn)
|
||||
{
|
||||
case CarDirection::ExitHighwayToRight: imageName = @"ic_cp_exit_highway_to_right"; break;
|
||||
case CarDirection::TurnSlightRight: imageName = @"ic_cp_slight_right"; break;
|
||||
case CarDirection::TurnRight: imageName = @"ic_cp_simple_right"; break;
|
||||
@@ -284,9 +307,8 @@
|
||||
case CarDirection::Count:
|
||||
case CarDirection::None: imageName = isPrimary ? @"ic_cp_straight" : nil; break;
|
||||
}
|
||||
if (!isPrimary && imageName != nil) {
|
||||
if (!isPrimary && imageName != nil)
|
||||
imageName = [NSString stringWithFormat:@"%@_then", imageName];
|
||||
}
|
||||
return imageName;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,9 +30,11 @@ enum class GeoMode
|
||||
BicycleRouting
|
||||
};
|
||||
|
||||
std::string DebugPrint(GeoMode geoMode) {
|
||||
std::string DebugPrint(GeoMode geoMode)
|
||||
{
|
||||
using enum GeoMode;
|
||||
switch (geoMode) {
|
||||
switch (geoMode)
|
||||
{
|
||||
case Pending: return "Pending";
|
||||
case InPosition: return "InPosition";
|
||||
case NotInPosition: return "NotInPosition";
|
||||
@@ -44,8 +46,10 @@ std::string DebugPrint(GeoMode geoMode) {
|
||||
CHECK(false, ("Unsupported value", static_cast<int>(geoMode)));
|
||||
}
|
||||
|
||||
std::string DebugPrint(MWMMyPositionMode mode) {
|
||||
switch (mode) {
|
||||
std::string DebugPrint(MWMMyPositionMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case MWMMyPositionModePendingPosition: return "MWMMyPositionModePendingPosition";
|
||||
case MWMMyPositionModeNotFollowNoPosition: return "MWMMyPositionModeNotFollowNoPosition";
|
||||
case MWMMyPositionModeNotFollow: return "MWMMyPositionModeNotFollow";
|
||||
@@ -55,8 +59,10 @@ std::string DebugPrint(MWMMyPositionMode mode) {
|
||||
CHECK(false, ("Unsupported value", static_cast<int>(mode)));
|
||||
}
|
||||
|
||||
std::string DebugPrint(MWMLocationStatus status) {
|
||||
switch (status) {
|
||||
std::string DebugPrint(MWMLocationStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MWMLocationStatusNoError: return "MWMLocationStatusNoError";
|
||||
case MWMLocationStatusNotSupported: return "MWMLocationStatusNotSupported";
|
||||
case MWMLocationStatusDenied: return "MWMLocationStatusDenied";
|
||||
@@ -66,8 +72,10 @@ std::string DebugPrint(MWMLocationStatus status) {
|
||||
CHECK(false, ("Unsupported value", static_cast<int>(status)));
|
||||
}
|
||||
|
||||
std::string DebugPrint(CLAuthorizationStatus status) {
|
||||
switch (status) {
|
||||
std::string DebugPrint(CLAuthorizationStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case kCLAuthorizationStatusNotDetermined: return "kCLAuthorizationStatusNotDetermined";
|
||||
case kCLAuthorizationStatusRestricted: return "kCLAuthorizationStatusRestricted";
|
||||
case kCLAuthorizationStatusDenied: return "kCLAuthorizationStatusDenied";
|
||||
@@ -92,32 +100,25 @@ struct GeoModeSettings
|
||||
std::map<GeoMode, GeoModeSettings> const kGeoSettings{
|
||||
{GeoMode::Pending,
|
||||
{.distanceFilter = kCLDistanceFilterNone,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBestForNavigation}}},
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBestForNavigation}}},
|
||||
{GeoMode::InPosition,
|
||||
{.distanceFilter = 2,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBest}}},
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBest}}},
|
||||
{GeoMode::NotInPosition,
|
||||
{.distanceFilter = 5,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBest}}},
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBest}}},
|
||||
{GeoMode::FollowAndRotate,
|
||||
{.distanceFilter = 2,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBest}}},
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBest}}},
|
||||
{GeoMode::VehicleRouting,
|
||||
{.distanceFilter = kCLDistanceFilterNone,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBest}}},
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBest}}},
|
||||
{GeoMode::PedestrianRouting,
|
||||
{.distanceFilter = 2,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBest}}},
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBest}}},
|
||||
{GeoMode::BicycleRouting,
|
||||
{.distanceFilter = 2,
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation,
|
||||
.battery = kCLLocationAccuracyBest}}}};
|
||||
.accuracy = {.charging = kCLLocationAccuracyBestForNavigation, .battery = kCLLocationAccuracyBest}}}};
|
||||
|
||||
BOOL keepRunningInBackground()
|
||||
{
|
||||
@@ -135,14 +136,16 @@ BOOL keepRunningInBackground()
|
||||
NSString * const kLocationPermissionRequestedKey = @"kLocationPermissionRequestedKey";
|
||||
NSString * const kLocationAlertNeedShowKey = @"kLocationAlertNeedShowKey";
|
||||
|
||||
BOOL needShowLocationAlert() {
|
||||
BOOL needShowLocationAlert()
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
if ([ud objectForKey:kLocationAlertNeedShowKey] == nil)
|
||||
return YES;
|
||||
return [ud boolForKey:kLocationAlertNeedShowKey];
|
||||
}
|
||||
|
||||
void setShowLocationAlert(BOOL needShow) {
|
||||
void setShowLocationAlert(BOOL needShow)
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
[ud setBool:needShow forKey:kLocationAlertNeedShowKey];
|
||||
}
|
||||
@@ -170,9 +173,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
{
|
||||
static MWMLocationManager * manager;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
manager = [[self alloc] initManager];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ manager = [[self alloc] initManager]; });
|
||||
return manager;
|
||||
}
|
||||
|
||||
@@ -180,9 +181,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
_observers = [Observers weakObjectsHashTable];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -192,11 +191,20 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
self.locationManager.delegate = nil;
|
||||
}
|
||||
|
||||
+ (void)start { [self manager].started = YES; }
|
||||
+ (void)start
|
||||
{
|
||||
[self manager].started = YES;
|
||||
}
|
||||
|
||||
+ (void)stop { [self manager].started = NO; }
|
||||
+ (void)stop
|
||||
{
|
||||
[self manager].started = NO;
|
||||
}
|
||||
|
||||
+ (BOOL)isStarted { return [self manager].started; }
|
||||
+ (BOOL)isStarted
|
||||
{
|
||||
return [self manager].started;
|
||||
}
|
||||
|
||||
#pragma mark - Add/Remove Observers
|
||||
|
||||
@@ -211,9 +219,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
|
||||
+ (void)removeObserver:(Observer)observer
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[self manager].observers removeObject:observer];
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [[self manager].observers removeObject:observer]; });
|
||||
}
|
||||
|
||||
#pragma mark - App Life Cycle
|
||||
@@ -238,8 +244,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
+ (CLLocation *)lastLocation
|
||||
{
|
||||
MWMLocationManager * manager = [self manager];
|
||||
if (!manager.started || !manager.lastLocationInfo ||
|
||||
manager.lastLocationInfo.horizontalAccuracy < 0 ||
|
||||
if (!manager.started || !manager.lastLocationInfo || manager.lastLocationInfo.horizontalAccuracy < 0 ||
|
||||
manager.lastLocationStatus != MWMLocationStatusNoError)
|
||||
return nil;
|
||||
return manager.lastLocationInfo;
|
||||
@@ -248,8 +253,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
+ (BOOL)isLocationProhibited
|
||||
{
|
||||
auto const status = [self manager].lastLocationStatus;
|
||||
return status == MWMLocationStatusDenied ||
|
||||
status == MWMLocationStatusGPSIsOff;
|
||||
return status == MWMLocationStatusDenied || status == MWMLocationStatusGPSIsOff;
|
||||
}
|
||||
|
||||
+ (CLHeading *)lastHeading
|
||||
@@ -269,22 +273,18 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
if (self.lastLocationStatus != MWMLocationStatusNoError)
|
||||
GetFramework().OnLocationError((location::TLocationError)self.lastLocationStatus);
|
||||
for (Observer observer in self.observers)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(onLocationError:)])
|
||||
[observer onLocationError:self.lastLocationStatus];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processHeadingUpdate:(CLHeading *)headingInfo
|
||||
{
|
||||
self.lastHeadingInfo = headingInfo;
|
||||
GetFramework().OnCompassUpdate(location_util::compassInfoFromHeading(headingInfo));
|
||||
for (Observer observer in self.observers)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(onHeadingUpdate:)])
|
||||
[observer onHeadingUpdate:headingInfo];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processLocationUpdate:(CLLocation *)locationInfo
|
||||
{
|
||||
@@ -304,11 +304,9 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
self.lastLocationInfo = locationInfo;
|
||||
self.locationSource = source;
|
||||
for (Observer observer in self.observers)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(onLocationUpdate:)])
|
||||
[observer onLocationUpdate:locationInfo];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Location Status
|
||||
|
||||
@@ -317,26 +315,25 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
_lastLocationStatus = lastLocationStatus;
|
||||
switch (lastLocationStatus)
|
||||
{
|
||||
case MWMLocationStatusNoError:
|
||||
break;
|
||||
case MWMLocationStatusNoError: break;
|
||||
case MWMLocationStatusNotSupported:
|
||||
[[MWMAlertViewController activeAlertController] presentLocationServiceNotSupportedAlert];
|
||||
break;
|
||||
case MWMLocationStatusDenied:
|
||||
if (needShowLocationAlert()) {
|
||||
[[MWMAlertViewController activeAlertController] presentLocationAlertWithCancelBlock:^{
|
||||
setShowLocationAlert(NO);
|
||||
}];
|
||||
if (needShowLocationAlert())
|
||||
{
|
||||
[[MWMAlertViewController activeAlertController]
|
||||
presentLocationAlertWithCancelBlock:^{ setShowLocationAlert(NO); }];
|
||||
}
|
||||
break;
|
||||
case MWMLocationStatusGPSIsOff:
|
||||
if (needShowLocationAlert()) {
|
||||
if (needShowLocationAlert())
|
||||
{
|
||||
[[MWMAlertViewController activeAlertController] presentLocationServicesDisabledAlert];
|
||||
setShowLocationAlert(NO);
|
||||
}
|
||||
break;
|
||||
case MWMLocationStatusTimeout:
|
||||
CHECK(false, ("MWMLocationStatusTimeout is only used in Qt/Desktop builds"));
|
||||
case MWMLocationStatusTimeout: CHECK(false, ("MWMLocationStatusTimeout is only used in Qt/Desktop builds"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,16 +416,10 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
case GeoMode::Pending:
|
||||
case GeoMode::InPosition:
|
||||
case GeoMode::NotInPosition:
|
||||
case GeoMode::FollowAndRotate:
|
||||
locationManager.activityType = CLActivityTypeOther;
|
||||
break;
|
||||
case GeoMode::VehicleRouting:
|
||||
locationManager.activityType = CLActivityTypeAutomotiveNavigation;
|
||||
break;
|
||||
case GeoMode::FollowAndRotate: locationManager.activityType = CLActivityTypeOther; break;
|
||||
case GeoMode::VehicleRouting: locationManager.activityType = CLActivityTypeAutomotiveNavigation; break;
|
||||
case GeoMode::PedestrianRouting:
|
||||
case GeoMode::BicycleRouting:
|
||||
locationManager.activityType = CLActivityTypeOtherNavigation;
|
||||
break;
|
||||
case GeoMode::BicycleRouting: locationManager.activityType = CLActivityTypeOtherNavigation; break;
|
||||
}
|
||||
|
||||
[MWMLocationManager refreshGeoModeSettingsFor:self.locationManager geoMode:self.geoMode];
|
||||
@@ -437,14 +428,12 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
+ (void)refreshGeoModeSettingsFor:(CLLocationManager *)locationManager geoMode:(GeoMode)geoMode
|
||||
{
|
||||
UIDeviceBatteryState const state = UIDevice.currentDevice.batteryState;
|
||||
BOOL const isCharging =
|
||||
(state == UIDeviceBatteryStateCharging || state == UIDeviceBatteryStateFull);
|
||||
BOOL const isCharging = (state == UIDeviceBatteryStateCharging || state == UIDeviceBatteryStateFull);
|
||||
GeoModeSettings const settings = kGeoSettings.at(geoMode);
|
||||
locationManager.desiredAccuracy =
|
||||
isCharging ? settings.accuracy.charging : settings.accuracy.battery;
|
||||
locationManager.desiredAccuracy = isCharging ? settings.accuracy.charging : settings.accuracy.battery;
|
||||
locationManager.distanceFilter = settings.distanceFilter;
|
||||
LOG(LINFO, ("Refreshed GeoMode settings: accuracy", locationManager.desiredAccuracy,
|
||||
"distance filter", locationManager.distanceFilter, "charging", isCharging));
|
||||
LOG(LINFO, ("Refreshed GeoMode settings: accuracy", locationManager.desiredAccuracy, "distance filter",
|
||||
locationManager.distanceFilter, "charging", isCharging));
|
||||
}
|
||||
|
||||
- (CLLocationManager *)locationManager
|
||||
@@ -467,8 +456,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
[self processHeadingUpdate:heading];
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager *)manager
|
||||
didUpdateLocations:(NSArray<CLLocation *> *)locations
|
||||
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
|
||||
{
|
||||
CLLocation * location = locations.lastObject;
|
||||
// According to documentation, lat and lon are valid only if horizontalAccuracy is non-negative.
|
||||
@@ -507,19 +495,17 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
[self processLocationStatus:MWMLocationStatusDenied];
|
||||
}
|
||||
|
||||
// Delegate's method didChangeAuthorizationStatus is used to handle the authorization status when the application finishes launching
|
||||
// or user changes location access in the application settings.
|
||||
// Delegate's method didChangeAuthorizationStatus is used to handle the authorization status when the application
|
||||
// finishes launching or user changes location access in the application settings.
|
||||
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager
|
||||
{
|
||||
LOG(LWARNING, ("CLLocationManagerDelegate: Authorization status has changed to", DebugPrint(manager.authorizationStatus)));
|
||||
switch (manager.authorizationStatus) {
|
||||
LOG(LWARNING,
|
||||
("CLLocationManagerDelegate: Authorization status has changed to", DebugPrint(manager.authorizationStatus)));
|
||||
switch (manager.authorizationStatus)
|
||||
{
|
||||
case kCLAuthorizationStatusAuthorizedWhenInUse:
|
||||
case kCLAuthorizationStatusAuthorizedAlways:
|
||||
[self startUpdatingLocationFor:manager];
|
||||
break;
|
||||
case kCLAuthorizationStatusNotDetermined:
|
||||
[manager requestWhenInUseAuthorization];
|
||||
break;
|
||||
case kCLAuthorizationStatusAuthorizedAlways: [self startUpdatingLocationFor:manager]; break;
|
||||
case kCLAuthorizationStatusNotDetermined: [manager requestWhenInUseAuthorization]; break;
|
||||
case kCLAuthorizationStatusRestricted:
|
||||
case kCLAuthorizationStatusDenied:
|
||||
if ([CLLocationManager locationServicesEnabled])
|
||||
@@ -547,9 +533,11 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
if (_started == started)
|
||||
return;
|
||||
NSNotificationCenter * notificationCenter = NSNotificationCenter.defaultCenter;
|
||||
if (started) {
|
||||
if (started)
|
||||
{
|
||||
_started = [self start];
|
||||
if (_started) {
|
||||
if (_started)
|
||||
{
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(orientationChanged)
|
||||
name:UIDeviceOrientationDidChangeNotification
|
||||
@@ -559,7 +547,9 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
name:UIDeviceBatteryStateDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_started = NO;
|
||||
[self stop];
|
||||
[notificationCenter removeObserver:self];
|
||||
@@ -591,8 +581,7 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
return YES;
|
||||
break;
|
||||
case kCLAuthorizationStatusRestricted:
|
||||
case kCLAuthorizationStatusDenied:
|
||||
break;
|
||||
case kCLAuthorizationStatusDenied: break;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
@@ -609,7 +598,8 @@ void setShowLocationAlert(BOOL needShow) {
|
||||
|
||||
#pragma mark - Location alert
|
||||
|
||||
+ (void)enableLocationAlert {
|
||||
+ (void)enableLocationAlert
|
||||
{
|
||||
setShowLocationAlert(YES);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,8 +45,7 @@ NSUInteger constexpr kMaxPredictionCount = 20;
|
||||
|
||||
- (BOOL)isActive
|
||||
{
|
||||
return self.isLastLocationValid && self.isLastPositionModeValid &&
|
||||
self.predictionsCount < kMaxPredictionCount;
|
||||
return self.isLastLocationValid && self.isLastPositionModeValid && self.predictionsCount < kMaxPredictionCount;
|
||||
}
|
||||
|
||||
- (void)restart
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
|
||||
@implementation MWMRoutePoint
|
||||
|
||||
- (instancetype)initWithLastLocationAndType:(MWMRoutePointType)type
|
||||
intermediateIndex:(size_t)intermediateIndex
|
||||
- (instancetype)initWithLastLocationAndType:(MWMRoutePointType)type intermediateIndex:(size_t)intermediateIndex
|
||||
{
|
||||
auto lastLocation = [MWMLocationManager lastLocation];
|
||||
if (!lastLocation)
|
||||
@@ -85,14 +84,10 @@
|
||||
intermediateIndex:(size_t)intermediateIndex
|
||||
{
|
||||
auto const pointD = m2::PointD(point.x, point.y);
|
||||
self = [self initWithPoint:pointD
|
||||
title:title
|
||||
subtitle:subtitle
|
||||
type:type intermediateIndex:intermediateIndex];
|
||||
self = [self initWithPoint:pointD title:title subtitle:subtitle type:type intermediateIndex:intermediateIndex];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)initWithPoint:(m2::PointD const &)point
|
||||
title:(NSString *)title
|
||||
subtitle:(NSString *)subtitle
|
||||
@@ -120,8 +115,14 @@
|
||||
NSAssert(_intermediateIndex >= 0 && _intermediateIndex <= 100, @"Invalid intermediateIndex");
|
||||
}
|
||||
|
||||
- (double)latitude { return mercator::YToLat(self.point.y); }
|
||||
- (double)longitude { return mercator::XToLon(self.point.x); }
|
||||
- (double)latitude
|
||||
{
|
||||
return mercator::YToLat(self.point.y);
|
||||
}
|
||||
- (double)longitude
|
||||
{
|
||||
return mercator::XToLon(self.point.x);
|
||||
}
|
||||
|
||||
- (NSString *)latLonString
|
||||
{
|
||||
@@ -159,9 +160,8 @@
|
||||
|
||||
return [NSString stringWithFormat:@"<%@: %p> Position: [%@, %@] | IsMyPosition: %@ | Type: %@ | "
|
||||
@"IntermediateIndex: %@ | Title: %@ | Subtitle: %@",
|
||||
[self class], self, @(_point.x), @(_point.y),
|
||||
_isMyPosition ? @"true" : @"false", type, @(_intermediateIndex),
|
||||
_title, _subtitle];
|
||||
[self class], self, @(_point.x), @(_point.y), _isMyPosition ? @"true" : @"false",
|
||||
type, @(_intermediateIndex), _title, _subtitle];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
+ (void)openRouteManagerTransaction
|
||||
{
|
||||
auto router = [MWMRouter router];
|
||||
router.routeManagerTransactionId =
|
||||
GetFramework().GetRoutingManager().OpenRoutePointsTransaction();
|
||||
router.routeManagerTransactionId = GetFramework().GetRoutingManager().OpenRoutePointsTransaction();
|
||||
}
|
||||
|
||||
+ (void)applyRouteManagerTransaction
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
#include <CoreApi/Framework.h>
|
||||
|
||||
#include "platform/distance.hpp"
|
||||
#include "platform/local_country_file_utils.hpp"
|
||||
#include "platform/localization.hpp"
|
||||
#include "platform/distance.hpp"
|
||||
|
||||
using namespace routing;
|
||||
|
||||
@@ -37,57 +37,65 @@ using namespace routing;
|
||||
|
||||
@end
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
char const * kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeImagesQueue";
|
||||
} // namespace
|
||||
|
||||
@implementation MWMRouter
|
||||
|
||||
+ (MWMRouter *)router {
|
||||
+ (MWMRouter *)router
|
||||
{
|
||||
static MWMRouter * router;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
router = [[self alloc] initRouter];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ router = [[self alloc] initRouter]; });
|
||||
return router;
|
||||
}
|
||||
|
||||
+ (BOOL)hasRouteAltitude {
|
||||
switch ([self type]) {
|
||||
+ (BOOL)hasRouteAltitude
|
||||
{
|
||||
switch ([self type])
|
||||
{
|
||||
case MWMRouterTypeVehicle:
|
||||
case MWMRouterTypePublicTransport:
|
||||
case MWMRouterTypeRuler:
|
||||
return NO;
|
||||
case MWMRouterTypeRuler: return NO;
|
||||
case MWMRouterTypePedestrian:
|
||||
case MWMRouterTypeBicycle:
|
||||
return GetFramework().GetRoutingManager().HasRouteAltitude();
|
||||
case MWMRouterTypeBicycle: return GetFramework().GetRoutingManager().HasRouteAltitude();
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)startRouting {
|
||||
+ (void)startRouting
|
||||
{
|
||||
[self start];
|
||||
}
|
||||
|
||||
+ (void)stopRouting {
|
||||
+ (void)stopRouting
|
||||
{
|
||||
[self stop:YES];
|
||||
}
|
||||
|
||||
+ (BOOL)isRoutingActive {
|
||||
+ (BOOL)isRoutingActive
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsRoutingActive();
|
||||
}
|
||||
+ (BOOL)isRouteBuilt {
|
||||
+ (BOOL)isRouteBuilt
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsRouteBuilt();
|
||||
}
|
||||
+ (BOOL)isRouteFinished {
|
||||
+ (BOOL)isRouteFinished
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsRouteFinished();
|
||||
}
|
||||
+ (BOOL)isRouteRebuildingOnly {
|
||||
+ (BOOL)isRouteRebuildingOnly
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsRouteRebuildingOnly();
|
||||
}
|
||||
+ (BOOL)isOnRoute {
|
||||
+ (BOOL)isOnRoute
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsRoutingFollowing();
|
||||
}
|
||||
+ (BOOL)IsRouteValid {
|
||||
+ (BOOL)IsRouteValid
|
||||
{
|
||||
return GetFramework().GetRoutingManager().IsRouteValid();
|
||||
}
|
||||
|
||||
@@ -96,7 +104,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return GetFramework().GetRoutingManager().IsSpeedCamLimitExceeded();
|
||||
}
|
||||
|
||||
+ (NSArray<MWMRoutePoint *> *)points {
|
||||
+ (NSArray<MWMRoutePoint *> *)points
|
||||
{
|
||||
NSMutableArray<MWMRoutePoint *> * points = [@[] mutableCopy];
|
||||
auto const routePoints = GetFramework().GetRoutingManager().GetRoutePoints();
|
||||
for (auto const & routePoint : routePoints)
|
||||
@@ -104,10 +113,12 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return [points copy];
|
||||
}
|
||||
|
||||
+ (NSInteger)pointsCount {
|
||||
+ (NSInteger)pointsCount
|
||||
{
|
||||
return GetFramework().GetRoutingManager().GetRoutePointsCount();
|
||||
}
|
||||
+ (MWMRoutePoint *)startPoint {
|
||||
+ (MWMRoutePoint *)startPoint
|
||||
{
|
||||
auto const routePoints = GetFramework().GetRoutingManager().GetRoutePoints();
|
||||
if (routePoints.empty())
|
||||
return nil;
|
||||
@@ -117,7 +128,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (MWMRoutePoint *)finishPoint {
|
||||
+ (MWMRoutePoint *)finishPoint
|
||||
{
|
||||
auto const routePoints = GetFramework().GetRoutingManager().GetRoutePoints();
|
||||
if (routePoints.empty())
|
||||
return nil;
|
||||
@@ -127,17 +139,21 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void)enableAutoAddLastLocation:(BOOL)enable {
|
||||
+ (void)enableAutoAddLastLocation:(BOOL)enable
|
||||
{
|
||||
[MWMRouter router].canAutoAddLastLocation = enable;
|
||||
}
|
||||
|
||||
+ (BOOL)canAddIntermediatePoint {
|
||||
+ (BOOL)canAddIntermediatePoint
|
||||
{
|
||||
return GetFramework().GetRoutingManager().CouldAddIntermediatePoint();
|
||||
}
|
||||
|
||||
- (instancetype)initRouter {
|
||||
- (instancetype)initRouter
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
self.altitudeImagesData = [@{} mutableCopy];
|
||||
self.renderAltitudeImagesQueue = dispatch_queue_create(kRenderAltitudeImagesQueueLabel, DISPATCH_QUEUE_SERIAL);
|
||||
self.routeManagerTransactionId = RoutingManager::InvalidRoutePointsTransactionId();
|
||||
@@ -150,17 +166,20 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)subscribeToEvents {
|
||||
+ (void)subscribeToEvents
|
||||
{
|
||||
[MWMFrameworkListener addObserver:[MWMRouter router]];
|
||||
[MWMLocationManager addObserver:[MWMRouter router]];
|
||||
}
|
||||
|
||||
+ (void)unsubscribeFromEvents {
|
||||
+ (void)unsubscribeFromEvents
|
||||
{
|
||||
[MWMFrameworkListener removeObserver:[MWMRouter router]];
|
||||
[MWMLocationManager removeObserver:[MWMRouter router]];
|
||||
}
|
||||
|
||||
+ (void)setType:(MWMRouterType)type {
|
||||
+ (void)setType:(MWMRouterType)type
|
||||
{
|
||||
if (type == self.type)
|
||||
return;
|
||||
|
||||
@@ -168,25 +187,31 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
GetFramework().GetRoutingManager().SetRouter(coreRouterType(type));
|
||||
}
|
||||
|
||||
+ (MWMRouterType)type {
|
||||
+ (MWMRouterType)type
|
||||
{
|
||||
return routerType(GetFramework().GetRoutingManager().GetRouter());
|
||||
}
|
||||
+ (void)disableFollowMode {
|
||||
+ (void)disableFollowMode
|
||||
{
|
||||
GetFramework().GetRoutingManager().DisableFollowMode();
|
||||
}
|
||||
+ (void)enableTurnNotifications:(BOOL)active {
|
||||
+ (void)enableTurnNotifications:(BOOL)active
|
||||
{
|
||||
GetFramework().GetRoutingManager().EnableTurnNotifications(active);
|
||||
}
|
||||
|
||||
+ (BOOL)areTurnNotificationsEnabled {
|
||||
+ (BOOL)areTurnNotificationsEnabled
|
||||
{
|
||||
return GetFramework().GetRoutingManager().AreTurnNotificationsEnabled();
|
||||
}
|
||||
|
||||
+ (void)setTurnNotificationsLocale:(NSString *)locale {
|
||||
+ (void)setTurnNotificationsLocale:(NSString *)locale
|
||||
{
|
||||
GetFramework().GetRoutingManager().SetTurnNotificationsLocale(locale.UTF8String);
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)turnNotifications {
|
||||
+ (NSArray<NSString *> *)turnNotifications
|
||||
{
|
||||
NSMutableArray<NSString *> * turnNotifications = [@[] mutableCopy];
|
||||
std::vector<std::string> notifications;
|
||||
auto announceStreets = [NSUserDefaults.standardUserDefaults boolForKey:@"UserDefaultsNeedToEnableStreetNamesTTS"];
|
||||
@@ -197,24 +222,29 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return [turnNotifications copy];
|
||||
}
|
||||
|
||||
+ (void)removePoint:(MWMRoutePoint *)point {
|
||||
+ (void)removePoint:(MWMRoutePoint *)point
|
||||
{
|
||||
RouteMarkData pt = point.routeMarkData;
|
||||
GetFramework().GetRoutingManager().RemoveRoutePoint(pt.m_pointType, pt.m_intermediateIndex);
|
||||
[[MWMNavigationDashboardManager sharedManager] onRoutePointsUpdated];
|
||||
}
|
||||
|
||||
+ (void)removePointAndRebuild:(MWMRoutePoint *)point {
|
||||
+ (void)removePointAndRebuild:(MWMRoutePoint *)point
|
||||
{
|
||||
if (!point)
|
||||
return;
|
||||
[self removePoint:point];
|
||||
[self rebuildWithBestRouter:NO];
|
||||
}
|
||||
|
||||
+ (void)removePoints {
|
||||
+ (void)removePoints
|
||||
{
|
||||
GetFramework().GetRoutingManager().RemoveRoutePoints();
|
||||
}
|
||||
+ (void)addPoint:(MWMRoutePoint *)point {
|
||||
if (!point) {
|
||||
+ (void)addPoint:(MWMRoutePoint *)point
|
||||
{
|
||||
if (!point)
|
||||
{
|
||||
NSAssert(NO, @"Point can not be nil");
|
||||
return;
|
||||
}
|
||||
@@ -224,34 +254,37 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
[[MWMNavigationDashboardManager sharedManager] onRoutePointsUpdated];
|
||||
}
|
||||
|
||||
+ (void)addPointAndRebuild:(MWMRoutePoint *)point {
|
||||
+ (void)addPointAndRebuild:(MWMRoutePoint *)point
|
||||
{
|
||||
if (!point)
|
||||
return;
|
||||
[self addPoint:point];
|
||||
[self rebuildWithBestRouter:NO];
|
||||
}
|
||||
|
||||
+ (void)buildFromPoint:(MWMRoutePoint *)startPoint bestRouter:(BOOL)bestRouter {
|
||||
+ (void)buildFromPoint:(MWMRoutePoint *)startPoint bestRouter:(BOOL)bestRouter
|
||||
{
|
||||
if (!startPoint)
|
||||
return;
|
||||
[self addPoint:startPoint];
|
||||
[self rebuildWithBestRouter:bestRouter];
|
||||
}
|
||||
|
||||
+ (void)buildToPoint:(MWMRoutePoint *)finishPoint bestRouter:(BOOL)bestRouter {
|
||||
+ (void)buildToPoint:(MWMRoutePoint *)finishPoint bestRouter:(BOOL)bestRouter
|
||||
{
|
||||
if (!finishPoint)
|
||||
return;
|
||||
[self addPoint:finishPoint];
|
||||
if (![self startPoint] && [MWMLocationManager lastLocation] && [MWMRouter router].canAutoAddLastLocation) {
|
||||
if (![self startPoint] && [MWMLocationManager lastLocation] && [MWMRouter router].canAutoAddLastLocation)
|
||||
[self addPoint:[[MWMRoutePoint alloc] initWithLastLocationAndType:MWMRoutePointTypeStart intermediateIndex:0]];
|
||||
}
|
||||
if ([self startPoint] && [self finishPoint])
|
||||
[self rebuildWithBestRouter:bestRouter];
|
||||
}
|
||||
|
||||
+ (void)buildApiRouteWithType:(MWMRouterType)type
|
||||
startPoint:(MWMRoutePoint *)startPoint
|
||||
finishPoint:(MWMRoutePoint *)finishPoint {
|
||||
finishPoint:(MWMRoutePoint *)finishPoint
|
||||
{
|
||||
if (!startPoint || !finishPoint)
|
||||
return;
|
||||
|
||||
@@ -266,13 +299,15 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
[self rebuildWithBestRouter:NO];
|
||||
}
|
||||
|
||||
+ (void)rebuildWithBestRouter:(BOOL)bestRouter {
|
||||
+ (void)rebuildWithBestRouter:(BOOL)bestRouter
|
||||
{
|
||||
[self clearAltitudeImagesData];
|
||||
|
||||
auto & rm = GetFramework().GetRoutingManager();
|
||||
auto const & points = rm.GetRoutePoints();
|
||||
auto const pointsCount = points.size();
|
||||
if (pointsCount < 2) {
|
||||
if (pointsCount < 2)
|
||||
{
|
||||
[self doStop:NO];
|
||||
[[MWMMapViewControlsManager manager] onRoutePrepare];
|
||||
return;
|
||||
@@ -284,7 +319,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
rm.BuildRoute();
|
||||
}
|
||||
|
||||
+ (void)start {
|
||||
+ (void)start
|
||||
{
|
||||
[self saveRoute];
|
||||
auto const doStart = ^{
|
||||
auto & rm = GetFramework().GetRoutingManager();
|
||||
@@ -316,9 +352,12 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
}
|
||||
};
|
||||
|
||||
if ([MWMSettings routingDisclaimerApproved]) {
|
||||
if ([MWMSettings routingDisclaimerApproved])
|
||||
{
|
||||
doStart();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
[[MWMAlertViewController activeAlertController] presentRoutingDisclaimerAlertWithOkBlock:^{
|
||||
doStart();
|
||||
[MWMSettings setRoutingDisclaimerApproved];
|
||||
@@ -326,13 +365,15 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)stop:(BOOL)removeRoutePoints {
|
||||
+ (void)stop:(BOOL)removeRoutePoints
|
||||
{
|
||||
[self doStop:removeRoutePoints];
|
||||
[self hideNavigationMapControls];
|
||||
[MWMRouter router].canAutoAddLastLocation = YES;
|
||||
}
|
||||
|
||||
+ (void)doStop:(BOOL)removeRoutePoints {
|
||||
+ (void)doStop:(BOOL)removeRoutePoints
|
||||
{
|
||||
[self clearAltitudeImagesData];
|
||||
GetFramework().GetRoutingManager().CloseRouting(removeRoutePoints);
|
||||
if (removeRoutePoints)
|
||||
@@ -340,7 +381,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
[MWMThemeManager setAutoUpdates:NO];
|
||||
}
|
||||
|
||||
- (void)updateFollowingInfo {
|
||||
- (void)updateFollowingInfo
|
||||
{
|
||||
if (![MWMRouter isRoutingActive])
|
||||
return;
|
||||
auto const & rm = GetFramework().GetRoutingManager();
|
||||
@@ -355,7 +397,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
[navManager updateFollowingInfo:info routePoints:[MWMRouter points] type:[MWMRouter type]];
|
||||
}
|
||||
|
||||
+ (void)routeAltitudeImageForSize:(CGSize)size completion:(MWMImageHeightBlock)block {
|
||||
+ (void)routeAltitudeImageForSize:(CGSize)size completion:(MWMImageHeightBlock)block
|
||||
{
|
||||
if (![self hasRouteAltitude])
|
||||
return;
|
||||
|
||||
@@ -364,7 +407,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
return;
|
||||
|
||||
// |altitudes| should not be used in the method after line below.
|
||||
dispatch_async(self.router.renderAltitudeImagesQueue, [=]() {
|
||||
dispatch_async(self.router.renderAltitudeImagesQueue, [=]()
|
||||
{
|
||||
auto router = self.router;
|
||||
CGFloat const screenScale = [UIScreen mainScreen].scale;
|
||||
CGSize const scaledSize = {size.width * screenScale, size.height * screenScale};
|
||||
@@ -405,7 +449,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)clearAltitudeImagesData {
|
||||
+ (void)clearAltitudeImagesData
|
||||
{
|
||||
auto router = self.router;
|
||||
dispatch_async(router.renderAltitudeImagesQueue, ^{
|
||||
[router.altitudeImagesData removeAllObjects];
|
||||
@@ -416,12 +461,14 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onLocationUpdate:(CLLocation *)location {
|
||||
- (void)onLocationUpdate:(CLLocation *)location
|
||||
{
|
||||
if (![MWMRouter isRoutingActive])
|
||||
return;
|
||||
auto tts = [MWMTextToSpeech tts];
|
||||
NSArray<NSString *> * turnNotifications = [MWMRouter turnNotifications];
|
||||
if ([MWMRouter isOnRoute] && tts.active) {
|
||||
if ([MWMRouter isOnRoute] && tts.active)
|
||||
{
|
||||
[tts playTurnNotifications:turnNotifications];
|
||||
[tts playWarningSound];
|
||||
}
|
||||
@@ -431,31 +478,27 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
|
||||
#pragma mark - MWMFrameworkRouteBuilderObserver
|
||||
|
||||
- (void)onRouteReady:(BOOL)hasWarnings {
|
||||
- (void)onRouteReady:(BOOL)hasWarnings
|
||||
{
|
||||
self.routingOptions = [MWMRoutingOptions new];
|
||||
GetFramework().DeactivateMapSelection();
|
||||
|
||||
auto startPoint = [MWMRouter startPoint];
|
||||
if (!startPoint || !startPoint.isMyPosition) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[MWMRouter disableFollowMode];
|
||||
});
|
||||
}
|
||||
if (!startPoint || !startPoint.isMyPosition)
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [MWMRouter disableFollowMode]; });
|
||||
|
||||
[[MWMMapViewControlsManager manager] onRouteReady:hasWarnings];
|
||||
[self updateFollowingInfo];
|
||||
}
|
||||
|
||||
- (void)processRouteBuilderEvent:(routing::RouterResultCode)code
|
||||
countries:(storage::CountriesSet const &)absentCountries {
|
||||
countries:(storage::CountriesSet const &)absentCountries
|
||||
{
|
||||
MWMMapViewControlsManager * mapViewControlsManager = [MWMMapViewControlsManager manager];
|
||||
switch (code) {
|
||||
case routing::RouterResultCode::NoError:
|
||||
[self onRouteReady:NO];
|
||||
break;
|
||||
case routing::RouterResultCode::HasWarnings:
|
||||
[self onRouteReady:YES];
|
||||
break;
|
||||
switch (code)
|
||||
{
|
||||
case routing::RouterResultCode::NoError: [self onRouteReady:NO]; break;
|
||||
case routing::RouterResultCode::HasWarnings: [self onRouteReady:YES]; break;
|
||||
case routing::RouterResultCode::RouteFileNotExist:
|
||||
case routing::RouterResultCode::InconsistentMWMandRoute:
|
||||
case routing::RouterResultCode::NeedMoreMaps:
|
||||
@@ -465,9 +508,7 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
[self presentDownloaderAlert:code countries:absentCountries];
|
||||
[[MWMNavigationDashboardManager sharedManager] onRouteError:L(@"routing_planning_error")];
|
||||
break;
|
||||
case routing::RouterResultCode::Cancelled:
|
||||
[mapViewControlsManager onRoutePrepare];
|
||||
break;
|
||||
case routing::RouterResultCode::Cancelled: [mapViewControlsManager onRoutePrepare]; break;
|
||||
case routing::RouterResultCode::StartPointNotFound:
|
||||
case routing::RouterResultCode::EndPointNotFound:
|
||||
case routing::RouterResultCode::NoCurrentPosition:
|
||||
@@ -483,12 +524,15 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processRouteBuilderProgress:(CGFloat)progress {
|
||||
- (void)processRouteBuilderProgress:(CGFloat)progress
|
||||
{
|
||||
[[MWMNavigationDashboardManager sharedManager] setRouteBuilderProgress:progress];
|
||||
}
|
||||
|
||||
- (void)processRouteRecommendation:(MWMRouterRecommendation)recommendation {
|
||||
switch (recommendation) {
|
||||
- (void)processRouteRecommendation:(MWMRouterRecommendation)recommendation
|
||||
{
|
||||
switch (recommendation)
|
||||
{
|
||||
case MWMRouterRecommendationRebuildAfterPointsLoading:
|
||||
[MWMRouter addPointAndRebuild:[[MWMRoutePoint alloc] initWithLastLocationAndType:MWMRoutePointTypeStart
|
||||
intermediateIndex:0]];
|
||||
@@ -498,9 +542,11 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
|
||||
#pragma mark - Alerts
|
||||
|
||||
- (void)presentDownloaderAlert:(routing::RouterResultCode)code countries:(storage::CountriesSet const &)countries {
|
||||
- (void)presentDownloaderAlert:(routing::RouterResultCode)code countries:(storage::CountriesSet const &)countries
|
||||
{
|
||||
MWMAlertViewController * activeAlertController = [MWMAlertViewController activeAlertController];
|
||||
if (!countries.empty()) {
|
||||
if (!countries.empty())
|
||||
{
|
||||
[activeAlertController presentDownloaderAlertWithCountries:countries
|
||||
code:code
|
||||
cancelBlock:^{
|
||||
@@ -509,101 +555,106 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm
|
||||
}
|
||||
downloadBlock:^(storage::CountriesVec const & downloadCountries, MWMVoidBlock onSuccess) {
|
||||
NSMutableArray * array = [NSMutableArray arrayWithCapacity:downloadCountries.size()];
|
||||
for (auto const &cid : downloadCountries) {
|
||||
for (auto const & cid : downloadCountries)
|
||||
[array addObject:@(cid.c_str())];
|
||||
}
|
||||
[[MWMStorage sharedStorage] downloadNodes:array onSuccess:onSuccess];
|
||||
}
|
||||
downloadCompleteBlock:^{
|
||||
[MWMRouter rebuildWithBestRouter:NO];
|
||||
}];
|
||||
} else if ([MWMRouter hasActiveDrivingOptions]) {
|
||||
[activeAlertController presentDefaultAlertWithTitle:L(@"unable_to_calc_alert_title")
|
||||
downloadCompleteBlock:^{ [MWMRouter rebuildWithBestRouter:NO]; }];
|
||||
}
|
||||
else if ([MWMRouter hasActiveDrivingOptions])
|
||||
{
|
||||
[activeAlertController
|
||||
presentDefaultAlertWithTitle:L(@"unable_to_calc_alert_title")
|
||||
message:L(@"unable_to_calc_alert_subtitle")
|
||||
rightButtonTitle:L(@"settings")
|
||||
leftButtonTitle:L(@"cancel")
|
||||
rightButtonAction:^{
|
||||
[[MapViewController sharedController] openDrivingOptions];
|
||||
}];
|
||||
} else {
|
||||
rightButtonAction:^{ [[MapViewController sharedController] openDrivingOptions]; }];
|
||||
}
|
||||
else
|
||||
{
|
||||
[activeAlertController presentAlert:code];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Save / Load route points
|
||||
|
||||
+ (void)saveRoute {
|
||||
+ (void)saveRoute
|
||||
{
|
||||
GetFramework().GetRoutingManager().SaveRoutePoints();
|
||||
}
|
||||
|
||||
+ (void)saveRouteIfNeeded {
|
||||
+ (void)saveRouteIfNeeded
|
||||
{
|
||||
if ([self isOnRoute])
|
||||
[self saveRoute];
|
||||
}
|
||||
|
||||
+ (void)restoreRouteIfNeeded {
|
||||
if ([MapsAppDelegate theApp].isDrapeEngineCreated) {
|
||||
+ (void)restoreRouteIfNeeded
|
||||
{
|
||||
if ([MapsAppDelegate theApp].isDrapeEngineCreated)
|
||||
{
|
||||
auto & rm = GetFramework().GetRoutingManager();
|
||||
if ([self isRoutingActive] || ![self hasSavedRoute]) {
|
||||
if ([self isRoutingActive] || ![self hasSavedRoute])
|
||||
{
|
||||
self.router.isRestoreProcessCompleted = YES;
|
||||
return;
|
||||
}
|
||||
rm.LoadRoutePoints([self](bool success) {
|
||||
rm.LoadRoutePoints([self](bool success)
|
||||
{
|
||||
if (success)
|
||||
[self rebuildWithBestRouter:YES];
|
||||
self.router.isRestoreProcessCompleted = YES;
|
||||
});
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self restoreRouteIfNeeded];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [self restoreRouteIfNeeded]; });
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isRestoreProcessCompleted {
|
||||
+ (BOOL)isRestoreProcessCompleted
|
||||
{
|
||||
return self.router.isRestoreProcessCompleted;
|
||||
}
|
||||
|
||||
+ (BOOL)hasSavedRoute {
|
||||
+ (BOOL)hasSavedRoute
|
||||
{
|
||||
return GetFramework().GetRoutingManager().HasSavedRoutePoints();
|
||||
}
|
||||
|
||||
+ (void)updateRoute {
|
||||
+ (void)updateRoute
|
||||
{
|
||||
MWMRoutingOptions * newOptions = [MWMRoutingOptions new];
|
||||
if ((self.isRoutingActive && !self.isOnRoute) && ![newOptions isEqual:[self router].routingOptions]) {
|
||||
if ((self.isRoutingActive && !self.isOnRoute) && ![newOptions isEqual:[self router].routingOptions])
|
||||
[self rebuildWithBestRouter:YES];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)hasActiveDrivingOptions {
|
||||
+ (BOOL)hasActiveDrivingOptions
|
||||
{
|
||||
return [MWMRoutingOptions new].hasOptions && self.type != MWMRouterTypeRuler;
|
||||
}
|
||||
|
||||
+ (void)avoidRoadTypeAndRebuild:(MWMRoadType)type {
|
||||
+ (void)avoidRoadTypeAndRebuild:(MWMRoadType)type
|
||||
{
|
||||
MWMRoutingOptions * options = [MWMRoutingOptions new];
|
||||
switch (type) {
|
||||
case MWMRoadTypeToll:
|
||||
options.avoidToll = YES;
|
||||
break;
|
||||
case MWMRoadTypeDirty:
|
||||
options.avoidDirty = YES;
|
||||
break;
|
||||
case MWMRoadTypeFerry:
|
||||
options.avoidFerry = YES;
|
||||
break;
|
||||
case MWMRoadTypeMotorway:
|
||||
options.avoidMotorway = YES;
|
||||
break;
|
||||
switch (type)
|
||||
{
|
||||
case MWMRoadTypeToll: options.avoidToll = YES; break;
|
||||
case MWMRoadTypeDirty: options.avoidDirty = YES; break;
|
||||
case MWMRoadTypeFerry: options.avoidFerry = YES; break;
|
||||
case MWMRoadTypeMotorway: options.avoidMotorway = YES; break;
|
||||
}
|
||||
[options save];
|
||||
[self rebuildWithBestRouter:YES];
|
||||
}
|
||||
|
||||
+ (void)showNavigationMapControls {
|
||||
+ (void)showNavigationMapControls
|
||||
{
|
||||
[[MWMMapViewControlsManager manager] onRouteStart];
|
||||
}
|
||||
|
||||
+ (void)hideNavigationMapControls {
|
||||
+ (void)hideNavigationMapControls
|
||||
{
|
||||
[[MWMMapViewControlsManager manager] onRouteStop];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#import <CoreApi/AppInfo.h>
|
||||
#import <CoreApi/Framework.h>
|
||||
#import <CoreApi/MWMCommon.h>
|
||||
#import <CoreSpotlight/CoreSpotlight.h>
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#import <CoreApi/Framework.h>
|
||||
#import <CoreApi/AppInfo.h>
|
||||
#import <CoreApi/MWMCommon.h>
|
||||
#import "MWMSearch+CoreSpotlight.h"
|
||||
#import "MWMSettings.h"
|
||||
|
||||
@@ -23,14 +23,15 @@
|
||||
|
||||
for (auto const & categoryKey : categoriesKeys)
|
||||
{
|
||||
CSSearchableItemAttributeSet * attrSet = [[CSSearchableItemAttributeSet alloc]
|
||||
initWithItemContentType: UTTypeItem.identifier];
|
||||
CSSearchableItemAttributeSet * attrSet =
|
||||
[[CSSearchableItemAttributeSet alloc] initWithItemContentType:UTTypeItem.identifier];
|
||||
|
||||
NSString * categoryName = nil;
|
||||
NSMutableDictionary<NSString *, NSString *> * localizedStrings = [@{} mutableCopy];
|
||||
|
||||
categories.ForEachSynonym(categoryKey, [&localizedStrings, &localeLanguageId, &categoryName](
|
||||
std::string const & name, std::string const & locale) {
|
||||
std::string const & name, std::string const & locale)
|
||||
{
|
||||
NSString * nsName = @(name.c_str());
|
||||
NSString * nsLocale = @(locale.c_str());
|
||||
if ([localeLanguageId isEqualToString:nsLocale])
|
||||
@@ -43,16 +44,20 @@
|
||||
attrSet.displayName = [[CSLocalizedString alloc] initWithLocalizedStrings:localizedStrings];
|
||||
|
||||
NSString * categoryKeyString = @(categoryKey.c_str());
|
||||
NSString * imageName = [NSString stringWithFormat:@"Search/Categories/%@", [categoryKeyString stringByReplacingOccurrencesOfString: @"category_" withString:@""]];
|
||||
UIImage * image = [UIImage imageNamed:imageName inBundle:nil compatibleWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle: UIUserInterfaceStyleLight]];
|
||||
NSString * imageName = [NSString
|
||||
stringWithFormat:@"Search/Categories/%@", [categoryKeyString stringByReplacingOccurrencesOfString:@"category_"
|
||||
withString:@""]];
|
||||
UIImage * image = [UIImage imageNamed:imageName
|
||||
inBundle:nil
|
||||
compatibleWithTraitCollection:[UITraitCollection
|
||||
traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]];
|
||||
UIGraphicsBeginImageContext(CGSizeMake(360, 360));
|
||||
[image drawInRect:CGRectMake(0, 0, 360, 360)];
|
||||
UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
attrSet.thumbnailData = UIImagePNGRepresentation(resizedImage);
|
||||
|
||||
CSSearchableItem * item =
|
||||
[[CSSearchableItem alloc] initWithUniqueIdentifier:categoryKeyString
|
||||
CSSearchableItem * item = [[CSSearchableItem alloc] initWithUniqueIdentifier:categoryKeyString
|
||||
domainIdentifier:@"comaps.app.categories"
|
||||
attributeSet:attrSet];
|
||||
[items addObject:item];
|
||||
@@ -64,8 +69,7 @@
|
||||
if (error)
|
||||
{
|
||||
NSError * err = error;
|
||||
LOG(LERROR,
|
||||
("addCategoriesToSpotlight failed: ", err.localizedDescription.UTF8String));
|
||||
LOG(LERROR, ("addCategoriesToSpotlight failed: ", err.localizedDescription.UTF8String));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
#import "SearchResult+Core.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include <CoreApi/MWMTypes.h>
|
||||
#include <CoreApi/Framework.h>
|
||||
#include <CoreApi/MWMTypes.h>
|
||||
|
||||
#include "platform/network_policy.hpp"
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
using Observer = id<MWMSearchObserver>;
|
||||
using Observers = NSHashTable<Observer>;
|
||||
} // namespace
|
||||
@@ -26,7 +27,8 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMSearch {
|
||||
@implementation MWMSearch
|
||||
{
|
||||
std::string m_query;
|
||||
std::string m_locale;
|
||||
bool m_isCategory;
|
||||
@@ -36,30 +38,35 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
#pragma mark - Instance
|
||||
|
||||
+ (MWMSearch *)manager {
|
||||
+ (MWMSearch *)manager
|
||||
{
|
||||
static MWMSearch * manager;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
manager = [[self alloc] initManager];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ manager = [[self alloc] initManager]; });
|
||||
return manager;
|
||||
}
|
||||
|
||||
- (instancetype)initManager {
|
||||
- (instancetype)initManager
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_observers = [Observers weakObjectsHashTable];
|
||||
[MWMFrameworkListener addObserver:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)searchEverywhere {
|
||||
- (void)searchEverywhere
|
||||
{
|
||||
self.lastSearchTimestamp += 1;
|
||||
NSUInteger const timestamp = self.lastSearchTimestamp;
|
||||
|
||||
search::EverywhereSearchParams params{
|
||||
m_query, m_locale, {} /* default timeout */, m_isCategory,
|
||||
m_query,
|
||||
m_locale,
|
||||
{} /* default timeout */,
|
||||
m_isCategory,
|
||||
// m_onResults
|
||||
[self, timestamp](search::Results results, std::vector<search::ProductInfo> productInfo)
|
||||
{
|
||||
@@ -76,16 +83,18 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
if (isEndMarker)
|
||||
self.searchCount -= 1;
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
GetFramework().GetSearchAPI().SearchEverywhere(std::move(params));
|
||||
self.searchCount += 1;
|
||||
}
|
||||
|
||||
- (void)searchInViewport {
|
||||
search::ViewportSearchParams params {
|
||||
m_query, m_locale, {} /* default timeout */, m_isCategory,
|
||||
- (void)searchInViewport
|
||||
{
|
||||
search::ViewportSearchParams params{m_query,
|
||||
m_locale,
|
||||
{} /* default timeout */,
|
||||
m_isCategory,
|
||||
// m_onStarted
|
||||
{},
|
||||
// m_onCompleted
|
||||
@@ -95,23 +104,20 @@ using Observers = NSHashTable<Observer>;
|
||||
return;
|
||||
if (!results.IsEndedCancelled())
|
||||
self->m_viewportResults = std::move(results);
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
GetFramework().GetSearchAPI().SearchInViewport(std::move(params));
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
- (void)update
|
||||
{
|
||||
if (m_query.empty())
|
||||
return;
|
||||
|
||||
switch (self.searchMode) {
|
||||
case SearchModeEverywhere:
|
||||
[self searchEverywhere];
|
||||
break;
|
||||
case SearchModeViewport:
|
||||
[self searchInViewport];
|
||||
break;
|
||||
switch (self.searchMode)
|
||||
{
|
||||
case SearchModeEverywhere: [self searchEverywhere]; break;
|
||||
case SearchModeViewport: [self searchInViewport]; break;
|
||||
case SearchModeEverywhereAndViewport:
|
||||
[self searchEverywhere];
|
||||
[self searchInViewport];
|
||||
@@ -121,28 +127,30 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
#pragma mark - Add/Remove Observers
|
||||
|
||||
+ (void)addObserver:(id<MWMSearchObserver>)observer {
|
||||
+ (void)addObserver:(id<MWMSearchObserver>)observer
|
||||
{
|
||||
[[MWMSearch manager].observers addObject:observer];
|
||||
}
|
||||
|
||||
+ (void)removeObserver:(id<MWMSearchObserver>)observer {
|
||||
+ (void)removeObserver:(id<MWMSearchObserver>)observer
|
||||
{
|
||||
[[MWMSearch manager].observers removeObject:observer];
|
||||
}
|
||||
|
||||
#pragma mark - Methods
|
||||
|
||||
+ (void)saveQuery:(SearchQuery *)query {
|
||||
+ (void)saveQuery:(SearchQuery *)query
|
||||
{
|
||||
if (!query.text || query.text.length == 0)
|
||||
return;
|
||||
|
||||
std::string locale = (!query.locale || query.locale == 0)
|
||||
? [MWMSearch manager]->m_locale
|
||||
: query.locale.UTF8String;
|
||||
std::string locale = (!query.locale || query.locale == 0) ? [MWMSearch manager]->m_locale : query.locale.UTF8String;
|
||||
std::string text = query.text.UTF8String;
|
||||
GetFramework().GetSearchAPI().SaveSearchQuery({std::move(locale), std::move(text)});
|
||||
}
|
||||
|
||||
+ (void)searchQuery:(SearchQuery *)query {
|
||||
+ (void)searchQuery:(SearchQuery *)query
|
||||
{
|
||||
if (!query.text)
|
||||
return;
|
||||
|
||||
@@ -160,39 +168,46 @@ using Observers = NSHashTable<Observer>;
|
||||
[manager update];
|
||||
}
|
||||
|
||||
+ (void)showResultAtIndex:(NSUInteger)index {
|
||||
+ (void)showResultAtIndex:(NSUInteger)index
|
||||
{
|
||||
auto const & result = [MWMSearch manager]->m_everywhereResults[index];
|
||||
GetFramework().StopLocationFollow();
|
||||
GetFramework().SelectSearchResult(result, true);
|
||||
}
|
||||
|
||||
+ (SearchResult *)resultWithContainerIndex:(NSUInteger)index {
|
||||
+ (SearchResult *)resultWithContainerIndex:(NSUInteger)index
|
||||
{
|
||||
SearchResult * result = [[SearchResult alloc] initWithResult:[MWMSearch manager]->m_everywhereResults[index]
|
||||
itemType:[MWMSearch resultTypeWithRow:index]
|
||||
index:index];
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSArray<SearchResult *> *)getResults {
|
||||
+ (NSArray<SearchResult *> *)getResults
|
||||
{
|
||||
NSMutableArray<SearchResult *> * results = [[NSMutableArray alloc] initWithCapacity:MWMSearch.resultsCount];
|
||||
for (NSUInteger i = 0; i < MWMSearch.resultsCount; ++i) {
|
||||
for (NSUInteger i = 0; i < MWMSearch.resultsCount; ++i)
|
||||
{
|
||||
SearchResult * result = [MWMSearch resultWithContainerIndex:i];
|
||||
[results addObject:result];
|
||||
}
|
||||
return [results copy];
|
||||
}
|
||||
|
||||
+ (SearchItemType)resultTypeWithRow:(NSUInteger)row {
|
||||
+ (SearchItemType)resultTypeWithRow:(NSUInteger)row
|
||||
{
|
||||
auto itemsIndex = [MWMSearch manager].itemsIndex;
|
||||
return [itemsIndex resultTypeWithRow:row];
|
||||
}
|
||||
|
||||
+ (NSUInteger)containerIndexWithRow:(NSUInteger)row {
|
||||
+ (NSUInteger)containerIndexWithRow:(NSUInteger)row
|
||||
{
|
||||
auto itemsIndex = [MWMSearch manager].itemsIndex;
|
||||
return [itemsIndex resultContainerIndexWithRow:row];
|
||||
}
|
||||
|
||||
- (void)reset {
|
||||
- (void)reset
|
||||
{
|
||||
self.lastSearchTimestamp += 1;
|
||||
GetFramework().GetSearchAPI().CancelAllSearches();
|
||||
|
||||
@@ -202,18 +217,21 @@ using Observers = NSHashTable<Observer>;
|
||||
[self onSearchResultsUpdated];
|
||||
}
|
||||
|
||||
+ (void)clear {
|
||||
+ (void)clear
|
||||
{
|
||||
auto manager = [MWMSearch manager];
|
||||
manager->m_query.clear();
|
||||
manager.suggestionsCount = 0;
|
||||
[manager reset];
|
||||
}
|
||||
|
||||
+ (SearchMode)searchMode {
|
||||
+ (SearchMode)searchMode
|
||||
{
|
||||
return [MWMSearch manager].searchMode;
|
||||
}
|
||||
|
||||
+ (void)setSearchMode:(SearchMode)mode {
|
||||
+ (void)setSearchMode:(SearchMode)mode
|
||||
{
|
||||
MWMSearch * manager = [MWMSearch manager];
|
||||
if (manager.searchMode == mode)
|
||||
return;
|
||||
@@ -221,15 +239,18 @@ using Observers = NSHashTable<Observer>;
|
||||
[manager update];
|
||||
}
|
||||
|
||||
+ (NSUInteger)suggestionsCount {
|
||||
+ (NSUInteger)suggestionsCount
|
||||
{
|
||||
return [MWMSearch manager].suggestionsCount;
|
||||
}
|
||||
|
||||
+ (NSUInteger)resultsCount {
|
||||
+ (NSUInteger)resultsCount
|
||||
{
|
||||
return [MWMSearch manager].itemsIndex.count;
|
||||
}
|
||||
|
||||
- (void)updateItemsIndexWithBannerReload:(BOOL)reloadBanner {
|
||||
- (void)updateItemsIndexWithBannerReload:(BOOL)reloadBanner
|
||||
{
|
||||
auto const resultsCount = self->m_everywhereResults.GetCount();
|
||||
auto const itemsIndex = [[SearchIndex alloc] initWithSuggestionsCount:self.suggestionsCount
|
||||
resultsCount:resultsCount];
|
||||
@@ -239,32 +260,33 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
#pragma mark - Notifications
|
||||
|
||||
- (void)onSearchStarted {
|
||||
for (Observer observer in self.observers) {
|
||||
- (void)onSearchStarted
|
||||
{
|
||||
for (Observer observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onSearchStarted)])
|
||||
[observer onSearchStarted];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onSearchCompleted {
|
||||
- (void)onSearchCompleted
|
||||
{
|
||||
[self updateItemsIndexWithBannerReload:YES];
|
||||
for (Observer observer in self.observers) {
|
||||
for (Observer observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onSearchCompleted)])
|
||||
[observer onSearchCompleted];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onSearchResultsUpdated {
|
||||
- (void)onSearchResultsUpdated
|
||||
{
|
||||
[self updateItemsIndexWithBannerReload:NO];
|
||||
for (Observer observer in self.observers) {
|
||||
for (Observer observer in self.observers)
|
||||
if ([observer respondsToSelector:@selector(onSearchResultsUpdated)])
|
||||
[observer onSearchResultsUpdated];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - MWMFrameworkDrapeObserver
|
||||
|
||||
- (void)processViewportChangedEvent {
|
||||
- (void)processViewportChangedEvent
|
||||
{
|
||||
if (!GetFramework().GetSearchAPI().IsViewportSearchActive())
|
||||
return;
|
||||
|
||||
@@ -272,19 +294,18 @@ using Observers = NSHashTable<Observer>;
|
||||
if (!isSearchCompleted)
|
||||
return;
|
||||
|
||||
switch (self.searchMode) {
|
||||
switch (self.searchMode)
|
||||
{
|
||||
case SearchModeEverywhere:
|
||||
case SearchModeViewport:
|
||||
break;
|
||||
case SearchModeEverywhereAndViewport:
|
||||
[self searchEverywhere];
|
||||
break;
|
||||
case SearchModeViewport: break;
|
||||
case SearchModeEverywhereAndViewport: [self searchEverywhere]; break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setSearchCount:(NSInteger)searchCount {
|
||||
- (void)setSearchCount:(NSInteger)searchCount
|
||||
{
|
||||
NSAssert((searchCount >= 0) && ((_searchCount == searchCount - 1) || (_searchCount == searchCount + 1)),
|
||||
@"Invalid search count update");
|
||||
if (searchCount > 0)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#import "SearchResult+Core.h"
|
||||
#import "CLLocation+Mercator.h"
|
||||
#import "MWMLocationManager.h"
|
||||
#import "SearchResult+Core.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#import "platform/localization.hpp"
|
||||
#import "platform/distance.hpp"
|
||||
#import "platform/localization.hpp"
|
||||
|
||||
#include "map/bookmark_helpers.hpp"
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
@implementation SearchResult
|
||||
|
||||
- (instancetype)initWithTitleText:(NSString *)titleText type:(SearchItemType)type suggestion:(NSString *)suggestion {
|
||||
- (instancetype)initWithTitleText:(NSString *)titleText type:(SearchItemType)type suggestion:(NSString *)suggestion
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_titleText = titleText;
|
||||
_itemType = type;
|
||||
_suggestion = suggestion;
|
||||
@@ -26,56 +28,71 @@
|
||||
|
||||
@implementation SearchResult (Core)
|
||||
|
||||
- (instancetype)initWithResult:(const search::Result &)result itemType:(SearchItemType)itemType index:(NSUInteger)index {
|
||||
- (instancetype)initWithResult:(search::Result const &)result itemType:(SearchItemType)itemType index:(NSUInteger)index
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_index = index;
|
||||
_titleText = result.GetString().empty() ? @(result.GetLocalizedFeatureType().c_str()) : @(result.GetString().c_str());
|
||||
_titleText =
|
||||
result.GetString().empty() ? @(result.GetLocalizedFeatureType().c_str()) : @(result.GetString().c_str());
|
||||
_addressText = @(result.GetAddress().c_str());
|
||||
_infoText = @(result.GetFeatureDescription().c_str());
|
||||
if (result.IsSuggest())
|
||||
_suggestion = @(result.GetSuggestionString().c_str());
|
||||
|
||||
_distanceText = nil;
|
||||
if (result.HasPoint()) {
|
||||
if (result.HasPoint())
|
||||
{
|
||||
auto const center = result.GetFeatureCenter();
|
||||
_point = CGPointMake(center.x, center.y);
|
||||
auto const [centerLat, centerLon] = mercator::ToLatLon(center);
|
||||
_coordinate = CLLocationCoordinate2DMake(centerLat, centerLon);
|
||||
|
||||
CLLocation * lastLocation = [MWMLocationManager lastLocation];
|
||||
if (lastLocation) {
|
||||
if (lastLocation)
|
||||
{
|
||||
double const distanceM = mercator::DistanceOnEarth(lastLocation.mercator, center);
|
||||
std::string const distanceStr = platform::Distance::CreateFormatted(distanceM).ToString();
|
||||
_distanceText = @(distanceStr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
switch (result.IsOpenNow()) {
|
||||
case osm::Yes: {
|
||||
const int minutes = result.GetMinutesUntilClosed();
|
||||
if (minutes < 60) { // less than 1 hour
|
||||
switch (result.IsOpenNow())
|
||||
{
|
||||
case osm::Yes:
|
||||
{
|
||||
int const minutes = result.GetMinutesUntilClosed();
|
||||
if (minutes < 60)
|
||||
{ // less than 1 hour
|
||||
_openStatusColor = [UIColor colorNamed:@"Base Colors/Yellow Color"];
|
||||
NSString * time = [NSString stringWithFormat:@"%d %@", minutes, L(@"minute")];
|
||||
_openStatusText = [NSString stringWithFormat:L(@"closes_in"), time];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_openStatusColor = [UIColor colorNamed:@"Base Colors/Green Color"];
|
||||
_openStatusText = L(@"editor_time_open");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case osm::No: {
|
||||
const int minutes = result.GetMinutesUntilOpen();
|
||||
if (minutes < 60) { // less than 1 hour
|
||||
case osm::No:
|
||||
{
|
||||
int const minutes = result.GetMinutesUntilOpen();
|
||||
if (minutes < 60)
|
||||
{ // less than 1 hour
|
||||
NSString * time = [NSString stringWithFormat:@"%d %@", minutes, L(@"minute")];
|
||||
_openStatusText = [NSString stringWithFormat:L(@"opens_in"), time];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_openStatusText = L(@"closed");
|
||||
}
|
||||
_openStatusColor = [UIColor colorNamed:@"Base Colors/Red Color"];
|
||||
break;
|
||||
}
|
||||
case osm::Unknown: {
|
||||
case osm::Unknown:
|
||||
{
|
||||
_openStatusText = nil;
|
||||
_openStatusColor = UIColor.clearColor;
|
||||
break;
|
||||
@@ -87,7 +104,8 @@
|
||||
|
||||
NSMutableArray<NSValue *> * ranges = [NSMutableArray array];
|
||||
size_t const rangesCount = result.GetHighlightRangesCount();
|
||||
for (size_t i = 0; i < rangesCount; ++i) {
|
||||
for (size_t i = 0; i < rangesCount; ++i)
|
||||
{
|
||||
auto const & range = result.GetHighlightRange(i);
|
||||
NSRange nsRange = NSMakeRange(range.first, range.second);
|
||||
[ranges addObject:[NSValue valueWithRange:nsRange]];
|
||||
@@ -96,12 +114,12 @@
|
||||
|
||||
_itemType = itemType;
|
||||
|
||||
if (result.GetResultType() == search::Result::Type::Feature) {
|
||||
if (result.GetResultType() == search::Result::Type::Feature)
|
||||
{
|
||||
auto const featureType = result.GetFeatureType();
|
||||
auto const bookmarkImage = GetBookmarkIconByFeatureType(featureType);
|
||||
_iconImageName = [NSString stringWithFormat:@"%@%@",
|
||||
@"ic_bm_",
|
||||
[@(kml::ToString(bookmarkImage).c_str()) lowercaseString]];
|
||||
_iconImageName =
|
||||
[NSString stringWithFormat:@"%@%@", @"ic_bm_", [@(kml::ToString(bookmarkImage).c_str()) lowercaseString]];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include "routing/routing_options.hpp"
|
||||
|
||||
@interface MWMRoutingOptions() {
|
||||
@interface MWMRoutingOptions ()
|
||||
{
|
||||
routing::RoutingOptions _options;
|
||||
}
|
||||
|
||||
@@ -10,67 +11,77 @@
|
||||
|
||||
@implementation MWMRoutingOptions
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
_options = routing::RoutingOptions::LoadCarOptionsFromSettings();
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)avoidToll {
|
||||
- (BOOL)avoidToll
|
||||
{
|
||||
return _options.Has(routing::RoutingOptions::Road::Toll);
|
||||
}
|
||||
|
||||
- (void)setAvoidToll:(BOOL)avoid {
|
||||
- (void)setAvoidToll:(BOOL)avoid
|
||||
{
|
||||
[self setOption:(routing::RoutingOptions::Road::Toll) enabled:avoid];
|
||||
}
|
||||
|
||||
- (BOOL)avoidDirty {
|
||||
- (BOOL)avoidDirty
|
||||
{
|
||||
return _options.Has(routing::RoutingOptions::Road::Dirty);
|
||||
}
|
||||
|
||||
- (void)setAvoidDirty:(BOOL)avoid {
|
||||
- (void)setAvoidDirty:(BOOL)avoid
|
||||
{
|
||||
[self setOption:(routing::RoutingOptions::Road::Dirty) enabled:avoid];
|
||||
}
|
||||
|
||||
- (BOOL)avoidFerry {
|
||||
- (BOOL)avoidFerry
|
||||
{
|
||||
return _options.Has(routing::RoutingOptions::Road::Ferry);
|
||||
}
|
||||
|
||||
- (void)setAvoidFerry:(BOOL)avoid {
|
||||
- (void)setAvoidFerry:(BOOL)avoid
|
||||
{
|
||||
[self setOption:(routing::RoutingOptions::Road::Ferry) enabled:avoid];
|
||||
}
|
||||
|
||||
- (BOOL)avoidMotorway {
|
||||
- (BOOL)avoidMotorway
|
||||
{
|
||||
return _options.Has(routing::RoutingOptions::Road::Motorway);
|
||||
}
|
||||
|
||||
- (void)setAvoidMotorway:(BOOL)avoid {
|
||||
- (void)setAvoidMotorway:(BOOL)avoid
|
||||
{
|
||||
[self setOption:(routing::RoutingOptions::Road::Motorway) enabled:avoid];
|
||||
}
|
||||
|
||||
- (BOOL)hasOptions {
|
||||
- (BOOL)hasOptions
|
||||
{
|
||||
return self.avoidToll || self.avoidDirty || self.avoidFerry || self.avoidMotorway;
|
||||
}
|
||||
|
||||
- (void)save {
|
||||
- (void)save
|
||||
{
|
||||
routing::RoutingOptions::SaveCarOptionsToSettings(_options);
|
||||
}
|
||||
|
||||
- (void)setOption:(routing::RoutingOptions::Road)option enabled:(BOOL)enabled {
|
||||
if (enabled) {
|
||||
- (void)setOption:(routing::RoutingOptions::Road)option enabled:(BOOL)enabled
|
||||
{
|
||||
if (enabled)
|
||||
_options.Add(option);
|
||||
} else {
|
||||
else
|
||||
_options.Remove(option);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if (![object isMemberOfClass:self.class]) {
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (![object isMemberOfClass:self.class])
|
||||
return NO;
|
||||
}
|
||||
MWMRoutingOptions * another = (MWMRoutingOptions *)object;
|
||||
return another.avoidToll == self.avoidToll && another.avoidDirty == self.avoidDirty &&
|
||||
another.avoidFerry == self.avoidFerry && another.avoidMotorway == self.avoidMotorway;
|
||||
|
||||
@@ -31,12 +31,11 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
{
|
||||
bool _ = true, on = true;
|
||||
GetFramework().Load3dMode(_, on);
|
||||
if (GetFramework().GetPowerManager().GetScheme() == power_management::Scheme::EconomyMaximum) {
|
||||
if (GetFramework().GetPowerManager().GetScheme() == power_management::Scheme::EconomyMaximum)
|
||||
return false;
|
||||
} else {
|
||||
else
|
||||
return on;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setBuildings3dViewEnabled:(BOOL)buildings3dViewEnabled;
|
||||
{
|
||||
@@ -130,9 +129,11 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
|
||||
+ (MWMTheme)theme
|
||||
{
|
||||
if ([MWMCarPlayService shared].isCarplayActivated) {
|
||||
if ([MWMCarPlayService shared].isCarplayActivated)
|
||||
{
|
||||
UIUserInterfaceStyle style = [[MWMCarPlayService shared] interfaceStyle];
|
||||
switch (style) {
|
||||
switch (style)
|
||||
{
|
||||
case UIUserInterfaceStyleLight: return MWMThemeDay;
|
||||
case UIUserInterfaceStyleDark: return MWMThemeNight;
|
||||
case UIUserInterfaceStyleUnspecified: break;
|
||||
@@ -158,11 +159,10 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
+ (NSInteger)powerManagement
|
||||
{
|
||||
Scheme scheme = GetFramework().GetPowerManager().GetScheme();
|
||||
if (scheme == Scheme::EconomyMaximum) {
|
||||
if (scheme == Scheme::EconomyMaximum)
|
||||
return 2;
|
||||
} else if (scheme == Scheme::Auto) {
|
||||
else if (scheme == Scheme::Auto)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -170,11 +170,10 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
+ (void)setPowerManagement:(NSInteger)powerManagement
|
||||
{
|
||||
Scheme scheme = Scheme::Normal;
|
||||
if (powerManagement == 2) {
|
||||
if (powerManagement == 2)
|
||||
scheme = Scheme::EconomyMaximum;
|
||||
} else if (powerManagement == 1) {
|
||||
else if (powerManagement == 1)
|
||||
scheme = Scheme::Auto;
|
||||
}
|
||||
GetFramework().GetPowerManager().SetScheme(scheme);
|
||||
}
|
||||
|
||||
@@ -185,7 +184,10 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
return enabled;
|
||||
}
|
||||
|
||||
+ (void)setRoutingDisclaimerApproved { settings::Set(kRoutingDisclaimerApprovedKey, true); }
|
||||
+ (void)setRoutingDisclaimerApproved
|
||||
{
|
||||
settings::Set(kRoutingDisclaimerApprovedKey, true);
|
||||
}
|
||||
+ (NSString *)spotlightLocaleLanguageId
|
||||
{
|
||||
return [NSUserDefaults.standardUserDefaults stringForKey:kSpotlightLocaleLanguageId];
|
||||
@@ -197,7 +199,10 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
[ud setObject:spotlightLocaleLanguageId forKey:kSpotlightLocaleLanguageId];
|
||||
}
|
||||
|
||||
+ (BOOL)largeFontSize { return GetFramework().LoadLargeFontsSize(); }
|
||||
+ (BOOL)largeFontSize
|
||||
{
|
||||
return GetFramework().LoadLargeFontsSize();
|
||||
}
|
||||
+ (void)setLargeFontSize:(BOOL)largeFontSize
|
||||
{
|
||||
GetFramework().SetLargeFontsSize(static_cast<bool>(largeFontSize));
|
||||
@@ -207,9 +212,8 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
{
|
||||
NSMutableDictionary<NSString *, NSString *> * availableLanguages = [[NSMutableDictionary alloc] init];
|
||||
auto const & v = StringUtf8Multilang::GetSupportedLanguages(false);
|
||||
for (auto i: v) {
|
||||
for (auto i : v)
|
||||
[availableLanguages setObject:@(std::string(i.m_name).c_str()) forKey:@(std::string(i.m_code).c_str())];
|
||||
}
|
||||
return availableLanguages;
|
||||
}
|
||||
|
||||
@@ -217,9 +221,8 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
{
|
||||
std::string mapLanguageCode;
|
||||
bool hasMapLanguageCode = settings::Get(kMapLanguageCode, mapLanguageCode);
|
||||
if (hasMapLanguageCode) {
|
||||
if (hasMapLanguageCode)
|
||||
return @(mapLanguageCode.c_str());
|
||||
}
|
||||
|
||||
return @"auto";
|
||||
}
|
||||
@@ -227,14 +230,16 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
+ (void)setMapLanguageCode:(NSString *)mapLanguageCode;
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
if ([mapLanguageCode isEqual: @"auto"]) {
|
||||
if ([mapLanguageCode isEqual:@"auto"])
|
||||
f.ResetMapLanguageCode();
|
||||
} else {
|
||||
else
|
||||
f.SetMapLanguageCode(std::string([mapLanguageCode UTF8String]));
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)transliteration { return GetFramework().LoadTransliteration(); }
|
||||
+ (BOOL)transliteration
|
||||
{
|
||||
return GetFramework().LoadTransliteration();
|
||||
}
|
||||
+ (void)setTransliteration:(BOOL)transliteration
|
||||
{
|
||||
bool const isTransliteration = static_cast<bool>(transliteration);
|
||||
@@ -268,21 +273,23 @@ NSString * const kUDFileLoggingEnabledKey = @"FileLoggingEnabledKey";
|
||||
+ (void)setICLoudSynchronizationEnabled:(BOOL)iCLoudSyncEnabled
|
||||
{
|
||||
[NSUserDefaults.standardUserDefaults setBool:iCLoudSyncEnabled forKey:kiCLoudSynchronizationEnabledKey];
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.iCloudSynchronizationDidChangeEnabledState object:nil];
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.iCloudSynchronizationDidChangeEnabledState
|
||||
object:nil];
|
||||
}
|
||||
|
||||
+ (void)initializeLogging {
|
||||
+ (void)initializeLogging
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[self setFileLoggingEnabled:[self isFileLoggingEnabled]];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ [self setFileLoggingEnabled:[self isFileLoggingEnabled]]; });
|
||||
}
|
||||
|
||||
+ (BOOL)isFileLoggingEnabled {
|
||||
+ (BOOL)isFileLoggingEnabled
|
||||
{
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kUDFileLoggingEnabledKey];
|
||||
}
|
||||
|
||||
+ (void)setFileLoggingEnabled:(BOOL)fileLoggingEnabled {
|
||||
+ (void)setFileLoggingEnabled:(BOOL)fileLoggingEnabled
|
||||
{
|
||||
[NSUserDefaults.standardUserDefaults setBool:fileLoggingEnabled forKey:kUDFileLoggingEnabledKey];
|
||||
[Logger setFileLoggingEnabled:fileLoggingEnabled];
|
||||
}
|
||||
|
||||
@@ -63,24 +63,26 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
@implementation MWMTextToSpeech
|
||||
|
||||
+ (MWMTextToSpeech *)tts {
|
||||
+ (MWMTextToSpeech *)tts
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static MWMTextToSpeech * tts = nil;
|
||||
dispatch_once(&onceToken, ^{
|
||||
tts = [[self alloc] initTTS];
|
||||
});
|
||||
dispatch_once(&onceToken, ^{ tts = [[self alloc] initTTS]; });
|
||||
return tts;
|
||||
}
|
||||
|
||||
+ (void)applicationDidBecomeActive {
|
||||
+ (void)applicationDidBecomeActive
|
||||
{
|
||||
auto tts = [self tts];
|
||||
tts.speechSynthesizer = nil;
|
||||
tts.speechVoice = nil;
|
||||
}
|
||||
|
||||
- (instancetype)initTTS {
|
||||
- (instancetype)initTTS
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (self)
|
||||
{
|
||||
_availableLanguages = availableLanguages();
|
||||
_observers = [Observers weakObjectsHashTable];
|
||||
|
||||
@@ -92,11 +94,9 @@ using Observers = NSHashTable<Observer>;
|
||||
preferedLanguageBcp47 = [AVSpeechSynthesisVoice currentLanguageCode];
|
||||
|
||||
std::pair<std::string, std::string> const lan =
|
||||
std::make_pair(preferedLanguageBcp47.UTF8String,
|
||||
tts::translateLocale(preferedLanguageBcp47.UTF8String));
|
||||
std::make_pair(preferedLanguageBcp47.UTF8String, tts::translateLocale(preferedLanguageBcp47.UTF8String));
|
||||
|
||||
if (find(_availableLanguages.begin(), _availableLanguages.end(), lan) !=
|
||||
_availableLanguages.end())
|
||||
if (find(_availableLanguages.begin(), _availableLanguages.end(), lan) != _availableLanguages.end())
|
||||
[self setNotificationsLocale:preferedLanguageBcp47];
|
||||
else
|
||||
[self setNotificationsLocale:kDefaultLanguage];
|
||||
@@ -106,7 +106,8 @@ using Observers = NSHashTable<Observer>;
|
||||
mode:AVAudioSessionModeVoicePrompt
|
||||
options:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers |
|
||||
AVAudioSessionCategoryOptionDuckOthers
|
||||
error:&err]) {
|
||||
error:&err])
|
||||
{
|
||||
LOG(LWARNING, ("Couldn't configure audio session: ", [err localizedDescription]));
|
||||
}
|
||||
|
||||
@@ -119,25 +120,38 @@ using Observers = NSHashTable<Observer>;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
- (void)dealloc
|
||||
{
|
||||
[[AVAudioSession sharedInstance] setActive:NO
|
||||
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
|
||||
error:nil];
|
||||
self.speechSynthesizer.delegate = nil;
|
||||
}
|
||||
- (std::vector<std::pair<std::string, std::string>>)availableLanguages { return _availableLanguages; }
|
||||
- (std::pair<std::string, std::string>)standardLanguage {
|
||||
- (std::vector<std::pair<std::string, std::string>>)availableLanguages
|
||||
{
|
||||
return _availableLanguages;
|
||||
}
|
||||
- (std::pair<std::string, std::string>)standardLanguage
|
||||
{
|
||||
return std::make_pair(kDefaultLanguage.UTF8String, tts::translateLocale(kDefaultLanguage.UTF8String));
|
||||
}
|
||||
- (void)setNotificationsLocale:(NSString *)locale {
|
||||
- (void)setNotificationsLocale:(NSString *)locale
|
||||
{
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
[ud setObject:locale forKey:kUserDefaultsTTSLanguageBcp47];
|
||||
[self createVoice:locale];
|
||||
}
|
||||
|
||||
- (BOOL)isValid { return _speechSynthesizer != nil && _speechVoice != nil; }
|
||||
+ (BOOL)isTTSEnabled { return [NSUserDefaults.standardUserDefaults boolForKey:kIsTTSEnabled]; }
|
||||
+ (void)setTTSEnabled:(BOOL)enabled {
|
||||
- (BOOL)isValid
|
||||
{
|
||||
return _speechSynthesizer != nil && _speechVoice != nil;
|
||||
}
|
||||
+ (BOOL)isTTSEnabled
|
||||
{
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kIsTTSEnabled];
|
||||
}
|
||||
+ (void)setTTSEnabled:(BOOL)enabled
|
||||
{
|
||||
if ([self isTTSEnabled] == enabled)
|
||||
return;
|
||||
auto tts = [self tts];
|
||||
@@ -150,8 +164,12 @@ using Observers = NSHashTable<Observer>;
|
||||
if (enabled)
|
||||
[tts setActive:YES];
|
||||
}
|
||||
+ (BOOL)isStreetNamesTTSEnabled { return [NSUserDefaults.standardUserDefaults boolForKey:kIsStreetNamesTTSEnabled]; }
|
||||
+ (void)setStreetNamesTTSEnabled:(BOOL)enabled {
|
||||
+ (BOOL)isStreetNamesTTSEnabled
|
||||
{
|
||||
return [NSUserDefaults.standardUserDefaults boolForKey:kIsStreetNamesTTSEnabled];
|
||||
}
|
||||
+ (void)setStreetNamesTTSEnabled:(BOOL)enabled
|
||||
{
|
||||
if ([self isStreetNamesTTSEnabled] == enabled)
|
||||
return;
|
||||
NSUserDefaults * ud = NSUserDefaults.standardUserDefaults;
|
||||
@@ -159,33 +177,34 @@ using Observers = NSHashTable<Observer>;
|
||||
[ud synchronize];
|
||||
}
|
||||
|
||||
- (void)setActive:(BOOL)active {
|
||||
- (void)setActive:(BOOL)active
|
||||
{
|
||||
if (![[self class] isTTSEnabled] || self.active == active)
|
||||
return;
|
||||
if (active && ![self isValid])
|
||||
[self createVoice:[[self class] savedLanguage]];
|
||||
[MWMRouter enableTurnNotifications:active];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self onTTSStatusUpdated];
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [self onTTSStatusUpdated]; });
|
||||
}
|
||||
|
||||
- (BOOL)active { return [[self class] isTTSEnabled] && [MWMRouter areTurnNotificationsEnabled]; }
|
||||
- (BOOL)active
|
||||
{
|
||||
return [[self class] isTTSEnabled] && [MWMRouter areTurnNotificationsEnabled];
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *, NSString *> *)availableLanguages
|
||||
{
|
||||
NSMutableDictionary<NSString *, NSString *> * availableLanguages = [[NSMutableDictionary alloc] init];
|
||||
auto const & v = [[self tts] availableLanguages];
|
||||
for (auto i: v) {
|
||||
for (auto i : v)
|
||||
[availableLanguages setObject:@(i.second.c_str()) forKey:@(i.first.c_str())];
|
||||
}
|
||||
return availableLanguages;
|
||||
}
|
||||
|
||||
+ (NSString *)selectedLanguage {
|
||||
if ([self savedLanguage] != nil) {
|
||||
+ (NSString *)selectedLanguage
|
||||
{
|
||||
if ([self savedLanguage] != nil)
|
||||
return [self savedLanguage];
|
||||
}
|
||||
|
||||
NSString * preferedLanguageBcp47 = [AVSpeechSynthesisVoice currentLanguageCode];
|
||||
|
||||
@@ -193,26 +212,24 @@ using Observers = NSHashTable<Observer>;
|
||||
std::make_pair(preferedLanguageBcp47.UTF8String, tts::translateLocale(preferedLanguageBcp47.UTF8String));
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> const availableLanguages = [[self tts] availableLanguages];
|
||||
if (find(availableLanguages.begin(), availableLanguages.end(), lan) !=
|
||||
availableLanguages.end()) {
|
||||
if (find(availableLanguages.begin(), availableLanguages.end(), lan) != availableLanguages.end())
|
||||
return preferedLanguageBcp47;
|
||||
}
|
||||
|
||||
return kDefaultLanguage;
|
||||
}
|
||||
|
||||
+ (NSString *)savedLanguage {
|
||||
+ (NSString *)savedLanguage
|
||||
{
|
||||
return [NSUserDefaults.standardUserDefaults stringForKey:kUserDefaultsTTSLanguageBcp47];
|
||||
}
|
||||
|
||||
+ (NSInteger)speedCameraMode
|
||||
{
|
||||
SpeedCameraManagerMode mode = GetFramework().GetRoutingManager().GetSpeedCamManager().GetMode();
|
||||
if (mode == SpeedCameraManagerMode::Auto) {
|
||||
if (mode == SpeedCameraManagerMode::Auto)
|
||||
return 2;
|
||||
} else if (mode == SpeedCameraManagerMode::Always) {
|
||||
else if (mode == SpeedCameraManagerMode::Always)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -220,16 +237,17 @@ using Observers = NSHashTable<Observer>;
|
||||
+ (void)setSpeedCameraMode:(NSInteger)speedCameraMode
|
||||
{
|
||||
SpeedCameraManagerMode mode = SpeedCameraManagerMode::Never;
|
||||
if (speedCameraMode == 2) {
|
||||
if (speedCameraMode == 2)
|
||||
mode = SpeedCameraManagerMode::Auto;
|
||||
} else if (speedCameraMode == 1) {
|
||||
else if (speedCameraMode == 1)
|
||||
mode = SpeedCameraManagerMode::Always;
|
||||
}
|
||||
GetFramework().GetRoutingManager().GetSpeedCamManager().SetMode(mode);
|
||||
}
|
||||
|
||||
- (void)createVoice:(NSString *)locale {
|
||||
if (!self.speechSynthesizer) {
|
||||
- (void)createVoice:(NSString *)locale
|
||||
{
|
||||
if (!self.speechSynthesizer)
|
||||
{
|
||||
self.speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
|
||||
self.speechSynthesizer.delegate = self;
|
||||
}
|
||||
@@ -242,38 +260,36 @@ using Observers = NSHashTable<Observer>;
|
||||
LOG(LWARNING, ("locale is nil. Trying default locale."));
|
||||
|
||||
AVSpeechSynthesisVoice * voice = nil;
|
||||
for (NSString * loc in candidateLocales) {
|
||||
if (@available(iOS 16.0, *)) {
|
||||
for (AVSpeechSynthesisVoice * aVoice in [AVSpeechSynthesisVoice speechVoices]) {
|
||||
if (voice == nil && aVoice.language == loc && aVoice.quality == AVSpeechSynthesisVoiceQualityPremium) {
|
||||
for (NSString * loc in candidateLocales)
|
||||
{
|
||||
if (@available(iOS 16.0, *))
|
||||
{
|
||||
for (AVSpeechSynthesisVoice * aVoice in [AVSpeechSynthesisVoice speechVoices])
|
||||
if (voice == nil && aVoice.language == loc && aVoice.quality == AVSpeechSynthesisVoiceQualityPremium)
|
||||
voice = aVoice;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (AVSpeechSynthesisVoice * aVoice in [AVSpeechSynthesisVoice speechVoices]) {
|
||||
if (voice == nil && aVoice.language == loc && aVoice.quality == AVSpeechSynthesisVoiceQualityEnhanced) {
|
||||
for (AVSpeechSynthesisVoice * aVoice in [AVSpeechSynthesisVoice speechVoices])
|
||||
if (voice == nil && aVoice.language == loc && aVoice.quality == AVSpeechSynthesisVoiceQualityEnhanced)
|
||||
voice = aVoice;
|
||||
}
|
||||
}
|
||||
if (voice == nil) {
|
||||
if (voice == nil)
|
||||
voice = [AVSpeechSynthesisVoice voiceWithLanguage:loc];
|
||||
}
|
||||
if (voice) {
|
||||
if (voice)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self.speechVoice = voice;
|
||||
if (voice) {
|
||||
if (voice)
|
||||
{
|
||||
std::string const twineLang = bcp47ToTwineLanguage(voice.language);
|
||||
if (twineLang.empty())
|
||||
LOG(LERROR, ("Cannot convert UI locale or default locale to twine language. MWMTextToSpeech "
|
||||
"is invalid."));
|
||||
else
|
||||
[MWMRouter setTurnNotificationsLocale:@(twineLang.c_str())];
|
||||
} else {
|
||||
LOG(LWARNING,
|
||||
("The UI language and English are not available for TTS. MWMTextToSpeech is invalid."));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LWARNING, ("The UI language and English are not available for TTS. MWMTextToSpeech is invalid."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,25 +299,26 @@ using Observers = NSHashTable<Observer>;
|
||||
[ttsTester playRandomTestString];
|
||||
}
|
||||
|
||||
|
||||
- (void)speakOneString:(NSString *)textToSpeak {
|
||||
- (void)speakOneString:(NSString *)textToSpeak
|
||||
{
|
||||
AVSpeechUtterance * utterance = [AVSpeechUtterance speechUtteranceWithString:textToSpeak];
|
||||
utterance.voice = self.speechVoice;
|
||||
utterance.rate = AVSpeechUtteranceDefaultSpeechRate;
|
||||
[self.speechSynthesizer speakUtterance:utterance];
|
||||
}
|
||||
|
||||
- (void)playTurnNotifications:(NSArray<NSString *> *)turnNotifications {
|
||||
- (void)playTurnNotifications:(NSArray<NSString *> *)turnNotifications
|
||||
{
|
||||
auto stopSession = ^{
|
||||
if (self.speechSynthesizer.isSpeaking)
|
||||
return;
|
||||
[[AVAudioSession sharedInstance]
|
||||
setActive:NO
|
||||
[[AVAudioSession sharedInstance] setActive:NO
|
||||
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
|
||||
error:nil];
|
||||
};
|
||||
|
||||
if (![MWMRouter isOnRoute] || !self.active) {
|
||||
if (![MWMRouter isOnRoute] || !self.active)
|
||||
{
|
||||
stopSession();
|
||||
return;
|
||||
}
|
||||
@@ -309,17 +326,22 @@ using Observers = NSHashTable<Observer>;
|
||||
if (![self isValid])
|
||||
[self createVoice:[[self class] savedLanguage]];
|
||||
|
||||
if (![self isValid]) {
|
||||
if (![self isValid])
|
||||
{
|
||||
stopSession();
|
||||
return;
|
||||
}
|
||||
|
||||
if (turnNotifications.count == 0) {
|
||||
if (turnNotifications.count == 0)
|
||||
{
|
||||
stopSession();
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
NSError * err = nil;
|
||||
if (![[AVAudioSession sharedInstance] setActive:YES error:&err]) {
|
||||
if (![[AVAudioSession sharedInstance] setActive:YES error:&err])
|
||||
{
|
||||
LOG(LWARNING, ("Couldn't activate audio session: ", [err localizedDescription]));
|
||||
return;
|
||||
}
|
||||
@@ -329,20 +351,26 @@ using Observers = NSHashTable<Observer>;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)playWarningSound {
|
||||
- (void)playWarningSound
|
||||
{
|
||||
if (!GetFramework().GetRoutingManager().GetSpeedCamManager().ShouldPlayBeepSignal())
|
||||
return;
|
||||
|
||||
[self.audioPlayer play];
|
||||
}
|
||||
|
||||
- (AVAudioPlayer *)audioPlayer {
|
||||
if (!_audioPlayer) {
|
||||
if (auto url = [[NSBundle mainBundle] URLForResource:@"Alert 5" withExtension:@"m4a"]) {
|
||||
- (AVAudioPlayer *)audioPlayer
|
||||
{
|
||||
if (!_audioPlayer)
|
||||
{
|
||||
if (auto url = [[NSBundle mainBundle] URLForResource:@"Alert 5" withExtension:@"m4a"])
|
||||
{
|
||||
NSError * error = nil;
|
||||
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
|
||||
CHECK(!error, (error.localizedDescription.UTF8String));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(false, ("Speed warning file not found"));
|
||||
}
|
||||
}
|
||||
@@ -350,7 +378,8 @@ using Observers = NSHashTable<Observer>;
|
||||
return _audioPlayer;
|
||||
}
|
||||
|
||||
- (void)play:(NSString *)text {
|
||||
- (void)play:(NSString *)text
|
||||
{
|
||||
if (![self isValid])
|
||||
[self createVoice:[[self class] savedLanguage]];
|
||||
|
||||
@@ -359,18 +388,21 @@ using Observers = NSHashTable<Observer>;
|
||||
|
||||
#pragma mark - MWMNavigationDashboardObserver
|
||||
|
||||
- (void)onTTSStatusUpdated {
|
||||
- (void)onTTSStatusUpdated
|
||||
{
|
||||
for (Observer observer in self.observers)
|
||||
[observer onTTSStatusUpdated];
|
||||
}
|
||||
|
||||
#pragma mark - Add/Remove Observers
|
||||
|
||||
+ (void)addObserver:(id<MWMTextToSpeechObserver>)observer {
|
||||
+ (void)addObserver:(id<MWMTextToSpeechObserver>)observer
|
||||
{
|
||||
[[self tts].observers addObject:observer];
|
||||
}
|
||||
|
||||
+ (void)removeObserver:(id<MWMTextToSpeechObserver>)observer {
|
||||
+ (void)removeObserver:(id<MWMTextToSpeechObserver>)observer
|
||||
{
|
||||
[[self tts].observers removeObject:observer];
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,14 @@ NSString * testStringsLanguage;
|
||||
|
||||
int testStringIndex;
|
||||
|
||||
- (void)playRandomTestString {
|
||||
- (void)playRandomTestString
|
||||
{
|
||||
NSString * currentTTSLanguage = MWMTextToSpeech.savedLanguage;
|
||||
if (testStrings == nil || ![currentTTSLanguage isEqualToString:testStringsLanguage]) {
|
||||
if (testStrings == nil || ![currentTTSLanguage isEqualToString:testStringsLanguage])
|
||||
{
|
||||
testStrings = [self getTestStrings:currentTTSLanguage];
|
||||
if (testStrings == nil) {
|
||||
if (testStrings == nil)
|
||||
{
|
||||
LOG(LWARNING, ("Couldn't load TTS test strings"));
|
||||
return;
|
||||
}
|
||||
@@ -31,17 +34,20 @@ int testStringIndex;
|
||||
testStringIndex = 0;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)getTestStrings:(NSString *)language {
|
||||
- (NSArray<NSString *> *)getTestStrings:(NSString *)language
|
||||
{
|
||||
NSString * twineLanguage = [NSString stringWithUTF8String:locale_translator::bcp47ToTwineLanguage(language).c_str()];
|
||||
NSString * languagePath = [NSBundle.mainBundle pathForResource:twineLanguage ofType:@"lproj"];
|
||||
if (languagePath == nil) {
|
||||
if (languagePath == nil)
|
||||
{
|
||||
LOG(LWARNING, ("Couldn't find translation file for ", twineLanguage.UTF8String));
|
||||
return nil;
|
||||
}
|
||||
NSBundle * bundle = [NSBundle bundleWithPath:languagePath];
|
||||
|
||||
NSMutableArray * appTips = [NSMutableArray new];
|
||||
for (int idx = 0; ; idx++) {
|
||||
for (int idx = 0;; idx++)
|
||||
{
|
||||
NSString * appTipKey = [NSString stringWithFormat:@"app_tip_%02d", idx];
|
||||
NSString * appTip = [bundle localizedStringForKey:appTipKey value:NotFoundDelimiter table:nil];
|
||||
if ([appTip isEqualToString:NotFoundDelimiter])
|
||||
|
||||
@@ -7,21 +7,25 @@
|
||||
|
||||
@implementation MWMTextToSpeechTest
|
||||
|
||||
- (void)testAvailableLanguages {
|
||||
- (void)testAvailableLanguages
|
||||
{
|
||||
MWMTextToSpeech * tts = [MWMTextToSpeech tts];
|
||||
std::vector<std::pair<std::string, std::string>> langs = tts.availableLanguages;
|
||||
decltype(langs)::value_type const defaultLang = std::make_pair("en-US", "English (United States)");
|
||||
XCTAssertTrue(std::find(langs.begin(), langs.end(), defaultLang) != langs.end());
|
||||
}
|
||||
- (void)testTranslateLocaleWithTwineString {
|
||||
- (void)testTranslateLocaleWithTwineString
|
||||
{
|
||||
XCTAssertEqual(tts::translateLocale("en"), "English");
|
||||
}
|
||||
|
||||
- (void)testTranslateLocaleWithBcp47String {
|
||||
- (void)testTranslateLocaleWithBcp47String
|
||||
{
|
||||
XCTAssertEqual(tts::translateLocale("en-US"), "English (United States)");
|
||||
}
|
||||
|
||||
- (void)testTranslateLocaleWithUnknownString {
|
||||
- (void)testTranslateLocaleWithUnknownString
|
||||
{
|
||||
XCTAssertEqual(tts::translateLocale("unknown"), "");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
NSString *RootId() { return @(GetFramework().GetStorage().GetRootId().c_str()); }
|
||||
NSString * RootId()
|
||||
{
|
||||
return @(GetFramework().GetStorage().GetRootId().c_str());
|
||||
}
|
||||
enum class State
|
||||
{
|
||||
Downloading,
|
||||
@@ -154,8 +157,8 @@ using namespace storage;
|
||||
|
||||
+ (instancetype)instanceWithPurpose:(Framework::DoAfterUpdate)todo
|
||||
{
|
||||
MWMAutoupdateController * controller =
|
||||
[[MWMAutoupdateController alloc] initWithNibName:[self className] bundle:NSBundle.mainBundle];
|
||||
MWMAutoupdateController * controller = [[MWMAutoupdateController alloc] initWithNibName:[self className]
|
||||
bundle:NSBundle.mainBundle];
|
||||
controller.todo = todo;
|
||||
auto view = static_cast<MWMAutoupdateView *>(controller.view);
|
||||
view.delegate = controller;
|
||||
@@ -172,7 +175,8 @@ using namespace storage;
|
||||
if (self.todo == Framework::DoAfterUpdate::AutoupdateMaps)
|
||||
{
|
||||
[view stateDownloading];
|
||||
[[MWMStorage sharedStorage] updateNode:RootId() onCancel:^{
|
||||
[[MWMStorage sharedStorage] updateNode:RootId()
|
||||
onCancel:^{
|
||||
[self updateSize];
|
||||
[view stateWaiting];
|
||||
}];
|
||||
@@ -186,9 +190,7 @@ using namespace storage;
|
||||
- (void)dismiss
|
||||
{
|
||||
[static_cast<MWMAutoupdateView *>(self.view) stopSpinner];
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[[MWMStorage sharedStorage] removeObserver:self];
|
||||
}];
|
||||
[self dismissViewControllerAnimated:YES completion:^{ [[MWMStorage sharedStorage] removeObserver:self]; }];
|
||||
}
|
||||
|
||||
- (void)updateSize
|
||||
@@ -206,32 +208,33 @@ using namespace storage;
|
||||
{
|
||||
MWMAutoupdateView * view = (MWMAutoupdateView *)self.view;
|
||||
[view stateDownloading];
|
||||
[[MWMStorage sharedStorage] updateNode:RootId() onCancel:^{
|
||||
[[MWMStorage sharedStorage] updateNode:RootId()
|
||||
onCancel:^{
|
||||
[self updateSize];
|
||||
[view stateWaiting];
|
||||
}];
|
||||
}
|
||||
- (IBAction)hideTap { [self dismiss]; }
|
||||
- (IBAction)hideTap
|
||||
{
|
||||
[self dismiss];
|
||||
}
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
auto view = static_cast<MWMAutoupdateView *>(self.view);
|
||||
UIAlertController * alertController =
|
||||
[UIAlertController alertControllerWithTitle:nil
|
||||
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:nil
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
alertController.popoverPresentationController.sourceView = view.secondaryButton;
|
||||
alertController.popoverPresentationController.sourceRect = view.secondaryButton.bounds;
|
||||
auto cancelDownloadAction =
|
||||
[UIAlertAction actionWithTitle:L(@"cancel_download")
|
||||
auto cancelDownloadAction = [UIAlertAction actionWithTitle:L(@"cancel_download")
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction * action) {
|
||||
[[MWMStorage sharedStorage] cancelDownloadNode:RootId()];
|
||||
[self dismiss];
|
||||
}];
|
||||
[alertController addAction:cancelDownloadAction];
|
||||
auto cancelAction =
|
||||
[UIAlertAction actionWithTitle:L(@"cancel") style:UIAlertActionStyleCancel handler:nil];
|
||||
auto cancelAction = [UIAlertAction actionWithTitle:L(@"cancel") style:UIAlertActionStyleCancel handler:nil];
|
||||
[alertController addAction:cancelAction];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
@@ -240,9 +243,11 @@ using namespace storage;
|
||||
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
||||
{
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
[coordinator
|
||||
animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
[static_cast<MWMAutoupdateView *>(self.view) updateForSize:size];
|
||||
} completion:nil];
|
||||
}
|
||||
completion:nil];
|
||||
}
|
||||
|
||||
- (void)updateProcessStatus:(CountryId const &)countryId
|
||||
@@ -259,7 +264,10 @@ using namespace storage;
|
||||
|
||||
#pragma mark - MWMCircularProgressProtocol
|
||||
|
||||
- (void)progressButtonPressed:(MWMCircularProgress *)progress { [self cancel]; }
|
||||
- (void)progressButtonPressed:(MWMCircularProgress *)progress
|
||||
{
|
||||
[self cancel];
|
||||
}
|
||||
|
||||
#pragma mark - MWMStorageObserver
|
||||
|
||||
@@ -298,9 +306,7 @@ using namespace storage;
|
||||
[[MWMStorage sharedStorage] cancelDownloadNode:RootId()];
|
||||
}
|
||||
|
||||
- (void)processCountry:(NSString *)countryId
|
||||
downloadedBytes:(uint64_t)downloadedBytes
|
||||
totalBytes:(uint64_t)totalBytes
|
||||
- (void)processCountry:(NSString *)countryId downloadedBytes:(uint64_t)downloadedBytes totalBytes:(uint64_t)totalBytes
|
||||
{
|
||||
if (m_updatingCountries.find(countryId.UTF8String) != m_updatingCountries.end())
|
||||
[self updateProcessStatus:countryId.UTF8String];
|
||||
|
||||
@@ -52,7 +52,8 @@ additionalSkipLanguageCodes:(std::vector<NSInteger>)additionalSkipLanguageCodes
|
||||
}
|
||||
|
||||
std::sort(m_languages.begin(), m_languages.end(),
|
||||
[&getIndex](StringUtf8Multilang::Lang const & lhs, StringUtf8Multilang::Lang const & rhs) {
|
||||
[&getIndex](StringUtf8Multilang::Lang const & lhs, StringUtf8Multilang::Lang const & rhs)
|
||||
{
|
||||
// Default name can be changed in advanced mode, but it should be last in list of names.
|
||||
if (getIndex(lhs.m_code) == kDefaultCode && getIndex(rhs.m_code) != kDefaultCode)
|
||||
return false;
|
||||
|
||||
@@ -28,15 +28,9 @@
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case Yes:
|
||||
self.segmentedControl.selectedSegmentIndex = 2;
|
||||
break;
|
||||
case No:
|
||||
self.segmentedControl.selectedSegmentIndex = 0;
|
||||
break;
|
||||
case Unknown:
|
||||
self.segmentedControl.selectedSegmentIndex = 1;
|
||||
break;
|
||||
case Yes: self.segmentedControl.selectedSegmentIndex = 2; break;
|
||||
case No: self.segmentedControl.selectedSegmentIndex = 0; break;
|
||||
case Unknown: self.segmentedControl.selectedSegmentIndex = 1; break;
|
||||
}
|
||||
|
||||
[self setTextColorWithSegmentedValue:value];
|
||||
@@ -47,12 +41,8 @@
|
||||
switch (value)
|
||||
{
|
||||
case Yes:
|
||||
case No:
|
||||
self.label.textColor = [UIColor blackPrimaryText];
|
||||
break;
|
||||
case Unknown:
|
||||
self.label.textColor = [UIColor blackHintText];
|
||||
break;
|
||||
case No: self.label.textColor = [UIColor blackPrimaryText]; break;
|
||||
case Unknown: self.label.textColor = [UIColor blackHintText]; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,18 +51,13 @@
|
||||
YesNoUnknown value;
|
||||
switch (self.segmentedControl.selectedSegmentIndex)
|
||||
{
|
||||
case 0:
|
||||
value = No;
|
||||
break;
|
||||
case 1:
|
||||
value = Unknown;
|
||||
break;
|
||||
case 2:
|
||||
value = Yes;
|
||||
break;
|
||||
case 0: value = No; break;
|
||||
case 1: value = Unknown; break;
|
||||
case 2: value = Yes; break;
|
||||
default:
|
||||
value = Unknown;
|
||||
NSAssert(false, @"Unexpected YesNoUnknown value %ld", static_cast<long>(self.segmentedControl.selectedSegmentIndex));
|
||||
NSAssert(false, @"Unexpected YesNoUnknown value %ld",
|
||||
static_cast<long>(self.segmentedControl.selectedSegmentIndex));
|
||||
}
|
||||
|
||||
[self.delegate cell:self changeSegmented:value];
|
||||
|
||||
@@ -107,8 +107,14 @@ std::vector<std::string> SliceKeys(std::vector<std::pair<std::string, std::strin
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { [searchBar resignFirstResponder]; }
|
||||
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
|
||||
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
|
||||
{
|
||||
[searchBar resignFirstResponder];
|
||||
}
|
||||
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
|
||||
{
|
||||
return UIBarPositionTopAttached;
|
||||
}
|
||||
- (void)searchBar:(UISearchBar *)searchBar setActiveState:(BOOL)isActiveState
|
||||
{
|
||||
[searchBar setShowsCancelButton:isActiveState animated:YES];
|
||||
@@ -153,13 +159,15 @@ std::vector<std::string> SliceKeys(std::vector<std::pair<std::string, std::strin
|
||||
|
||||
- (void)configTable
|
||||
{
|
||||
[self.tableView registerClass:[MWMTableViewCell class]
|
||||
forCellReuseIdentifier:[UITableViewCell className]];
|
||||
[self.tableView registerClass:[MWMTableViewCell class] forCellReuseIdentifier:[UITableViewCell className]];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)onCancel { [self.navigationController popViewControllerAnimated:YES]; }
|
||||
- (void)onCancel
|
||||
{
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
- (void)onDone
|
||||
{
|
||||
[self.delegate setSelectedCuisines:m_selectedCuisines];
|
||||
@@ -181,8 +189,7 @@ std::vector<std::string> SliceKeys(std::vector<std::pair<std::string, std::strin
|
||||
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
{
|
||||
auto cell =
|
||||
[tableView dequeueReusableCellWithCellClass:[UITableViewCell class] indexPath:indexPath];
|
||||
auto cell = [tableView dequeueReusableCellWithCellClass:[UITableViewCell class] indexPath:indexPath];
|
||||
NSInteger const index = indexPath.row;
|
||||
|
||||
auto const & dataSource = [self dataSourceForSection:indexPath.section];
|
||||
@@ -224,16 +231,13 @@ std::vector<std::string> SliceKeys(std::vector<std::pair<std::string, std::strin
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView * _Nonnull)tableView
|
||||
didSelectRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
- (void)tableView:(UITableView * _Nonnull)tableView didSelectRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
{
|
||||
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
[cell setSelected:NO animated:YES];
|
||||
BOOL const isAlreadySelected = cell.accessoryType == UITableViewCellAccessoryCheckmark;
|
||||
cell.accessoryType =
|
||||
isAlreadySelected ? UITableViewCellAccessoryNone : UITableViewCellAccessoryCheckmark;
|
||||
[self change:[self dataSourceForSection:indexPath.section][indexPath.row]
|
||||
selected:!isAlreadySelected];
|
||||
cell.accessoryType = isAlreadySelected ? UITableViewCellAccessoryNone : UITableViewCellAccessoryCheckmark;
|
||||
[self change:[self dataSourceForSection:indexPath.section][indexPath.row] selected:!isAlreadySelected];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#import "MWMEditorCategoryCell.h"
|
||||
#import "MWMEditorCellType.h"
|
||||
#import "MWMEditorNotesFooter.h"
|
||||
#import "MWMEditorSegmentedTableViewCell.hpp"
|
||||
#import "MWMEditorSelectTableViewCell.h"
|
||||
#import "MWMEditorSwitchTableViewCell.h"
|
||||
#import "MWMEditorSegmentedTableViewCell.hpp"
|
||||
#import "MWMEditorTextTableViewCell.h"
|
||||
#import "MWMNoteCell.h"
|
||||
#import "MWMObjectsCategorySelectorController.h"
|
||||
@@ -24,8 +24,8 @@
|
||||
#import <CoreApi/Framework.h>
|
||||
#import <CoreApi/StringUtils.h>
|
||||
|
||||
#include "platform/localization.hpp"
|
||||
#include "indexer/validate_and_format_contacts.hpp"
|
||||
#include "platform/localization.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -50,9 +50,8 @@ typedef NS_ENUM(NSUInteger, MWMEditorSection) {
|
||||
};
|
||||
|
||||
std::vector<MWMEditorCellID> const kSectionCategoryCellTypes{MWMEditorCellTypeCategory};
|
||||
std::vector<MWMEditorCellID> const kSectionAddressCellTypes {
|
||||
MWMEditorCellTypeStreet, MWMEditorCellTypeBuilding, MetadataID::FMD_POSTCODE
|
||||
};
|
||||
std::vector<MWMEditorCellID> const kSectionAddressCellTypes{MWMEditorCellTypeStreet, MWMEditorCellTypeBuilding,
|
||||
MetadataID::FMD_POSTCODE};
|
||||
|
||||
std::vector<MWMEditorCellID> const kSectionNoteCellTypes{MWMEditorCellTypeNote};
|
||||
std::vector<MWMEditorCellID> const kSectionButtonCellTypes{MWMEditorCellTypeReportButton};
|
||||
@@ -70,8 +69,7 @@ std::map<MWMEditorCellID, Class> const kCellType2Class {
|
||||
{MetadataID::FMD_SELF_SERVICE, [MWMEditorSegmentedTableViewCell class]},
|
||||
{MetadataID::FMD_OUTDOOR_SEATING, [MWMEditorSegmentedTableViewCell class]},
|
||||
{MWMEditorCellTypeNote, [MWMNoteCell class]},
|
||||
{MWMEditorCellTypeReportButton, [MWMButtonCell class]}
|
||||
};
|
||||
{MWMEditorCellTypeReportButton, [MWMButtonCell class]}};
|
||||
// Default class, if no entry in kCellType2Class.
|
||||
Class kDefaultCellTypeClass = [MWMEditorTextTableViewCell class];
|
||||
/// @return kDefaultCellTypeClass if cellType not specified in kCellType2Class.
|
||||
@@ -88,8 +86,7 @@ void cleanupAdditionalLanguages(std::vector<osm::LocalizedName> const & names,
|
||||
{
|
||||
base::EraseIf(newAdditionalLanguages, [&names](NSInteger x)
|
||||
{
|
||||
auto it = find_if(names.begin(), names.end(),
|
||||
[x](osm::LocalizedName const & name) { return name.m_code == x; });
|
||||
auto it = find_if(names.begin(), names.end(), [x](osm::LocalizedName const & name) { return name.m_code == x; });
|
||||
return it != names.end();
|
||||
});
|
||||
}
|
||||
@@ -125,11 +122,19 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@interface MWMEditorViewController ()<
|
||||
UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, MWMOpeningHoursEditorProtocol,
|
||||
MWMPlacePageOpeningHoursCellProtocol, MWMEditorCellProtocol, MWMCuisineEditorProtocol,
|
||||
MWMStreetEditorProtocol, MWMObjectsCategorySelectorDelegate, MWMNoteCellDelegate,
|
||||
MWMEditorAdditionalName, MWMButtonCellDelegate, MWMEditorAdditionalNamesProtocol>
|
||||
@interface MWMEditorViewController () <UITableViewDelegate,
|
||||
UITableViewDataSource,
|
||||
UITextFieldDelegate,
|
||||
MWMOpeningHoursEditorProtocol,
|
||||
MWMPlacePageOpeningHoursCellProtocol,
|
||||
MWMEditorCellProtocol,
|
||||
MWMCuisineEditorProtocol,
|
||||
MWMStreetEditorProtocol,
|
||||
MWMObjectsCategorySelectorDelegate,
|
||||
MWMNoteCellDelegate,
|
||||
MWMEditorAdditionalName,
|
||||
MWMButtonCellDelegate,
|
||||
MWMEditorAdditionalNamesProtocol>
|
||||
|
||||
@property(nonatomic) NSMutableDictionary<Class, UITableViewCell *> * offscreenCells;
|
||||
@property(nonatomic) NSMutableArray<NSIndexPath *> * invalidCells;
|
||||
@@ -191,8 +196,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
|
||||
- (void)configNavBar
|
||||
{
|
||||
self.title =
|
||||
L(self.isCreating ? @"editor_add_place_title" : @"editor_edit_place_title");
|
||||
self.title = L(self.isCreating ? @"editor_add_place_title" : @"editor_edit_place_title");
|
||||
self.navigationItem.rightBarButtonItem =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
|
||||
target:self
|
||||
@@ -234,9 +238,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
switch (f.SaveEditedMapObject(m_mapObject))
|
||||
{
|
||||
case osm::Editor::SaveResult::NoUnderlyingMapError:
|
||||
case osm::Editor::SaveResult::SavingError:
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
break;
|
||||
case osm::Editor::SaveResult::SavingError: [self.navigationController popToRootViewControllerAnimated:YES]; break;
|
||||
case osm::Editor::SaveResult::NothingWasChanged:
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
if (haveNote)
|
||||
@@ -247,9 +249,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
f.UpdatePlacePageInfoForCurrentSelection();
|
||||
[self.navigationController popToRootViewControllerAnimated:YES];
|
||||
break;
|
||||
case osm::Editor::SaveResult::NoFreeSpaceError:
|
||||
[self.alertController presentNotEnoughSpaceAlert];
|
||||
break;
|
||||
case osm::Editor::SaveResult::NoFreeSpaceError: [self.alertController presentNotEnoughSpaceAlert]; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,8 +289,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
_showAdditionalNames = showAdditionalNames;
|
||||
[self.additionalNamesHeader setShowAdditionalNames:showAdditionalNames];
|
||||
[self configTable];
|
||||
auto const additionalNamesSectionIt =
|
||||
find(m_sections.begin(), m_sections.end(), MWMEditorSectionAdditionalNames);
|
||||
auto const additionalNamesSectionIt = find(m_sections.begin(), m_sections.end(), MWMEditorSectionAdditionalNames);
|
||||
if (additionalNamesSectionIt == m_sections.end())
|
||||
{
|
||||
[self.tableView reloadData];
|
||||
@@ -330,10 +329,10 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
BOOL const isAddressEditable = m_mapObject.IsAddressEditable();
|
||||
auto editableProperties = m_mapObject.GetEditableProperties();
|
||||
// Remove fields that are already displayed in the Address section.
|
||||
editableProperties.erase(std::remove_if(editableProperties.begin(), editableProperties.end(), [](osm::MapObject::MetadataID mid)
|
||||
{
|
||||
return mid == MetadataID::FMD_POSTCODE || mid == MetadataID::FMD_BUILDING_LEVELS;
|
||||
}), editableProperties.end());
|
||||
editableProperties.erase(
|
||||
std::remove_if(editableProperties.begin(), editableProperties.end(), [](osm::MapObject::MetadataID mid)
|
||||
{ return mid == MetadataID::FMD_POSTCODE || mid == MetadataID::FMD_BUILDING_LEVELS; }),
|
||||
editableProperties.end());
|
||||
BOOL const isCreating = self.isCreating;
|
||||
BOOL const showNotesToOSMEditors = YES;
|
||||
|
||||
@@ -342,8 +341,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
auto const ds = m_mapObject.GetNamesDataSource();
|
||||
auto const & localizedNames = ds.names;
|
||||
cleanupAdditionalLanguages(localizedNames, m_newAdditionalLanguages);
|
||||
auto const cells =
|
||||
cellsForAdditionalNames(ds, m_newAdditionalLanguages, self.showAdditionalNames);
|
||||
auto const cells = cellsForAdditionalNames(ds, m_newAdditionalLanguages, self.showAdditionalNames);
|
||||
m_sections.push_back(MWMEditorSectionAdditionalNames);
|
||||
m_cells[MWMEditorSectionAdditionalNames] = cells;
|
||||
registerCellsForTableView(cells, self.tableView);
|
||||
@@ -523,13 +521,13 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
}
|
||||
case MWMEditorCellTypeAdditionalName:
|
||||
{
|
||||
MWMEditorAdditionalNameTableViewCell * tCell =
|
||||
static_cast<MWMEditorAdditionalNameTableViewCell *>(cell);
|
||||
MWMEditorAdditionalNameTableViewCell * tCell = static_cast<MWMEditorAdditionalNameTableViewCell *>(cell);
|
||||
auto const & localizedNames = m_mapObject.GetNamesDataSource().names;
|
||||
if (indexPath.row < localizedNames.size())
|
||||
{
|
||||
osm::LocalizedName const & name = localizedNames[indexPath.row];
|
||||
NSString * langName = indexPath.row == StringUtf8Multilang::kDefaultCode ? L(@"editor_default_language_hint") : ToNSString(name.m_langName);
|
||||
NSString * langName = indexPath.row == StringUtf8Multilang::kDefaultCode ? L(@"editor_default_language_hint")
|
||||
: ToNSString(name.m_langName);
|
||||
[tCell configWithDelegate:self
|
||||
langCode:name.m_code
|
||||
langName:langName
|
||||
@@ -546,9 +544,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
std::string name;
|
||||
// Default name can be changed in advanced mode.
|
||||
if (langCode == StringUtf8Multilang::kDefaultCode)
|
||||
{
|
||||
name = m_mapObject.GetDefaultName();
|
||||
}
|
||||
|
||||
[tCell configWithDelegate:self
|
||||
langCode:langCode
|
||||
@@ -597,16 +593,15 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
errorMessage:L(@"error_enter_correct_zip_code")
|
||||
isValid:isValid
|
||||
keyboardType:UIKeyboardTypeDefault];
|
||||
static_cast<MWMEditorTextTableViewCell *>(cell).textField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
|
||||
static_cast<MWMEditorTextTableViewCell *>(cell).textField.autocapitalizationType =
|
||||
UITextAutocapitalizationTypeAllCharacters;
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_BUILDING_LEVELS:
|
||||
{
|
||||
NSString * placeholder =
|
||||
[NSString stringWithFormat:L(@"editor_storey_number"),
|
||||
osm::EditableMapObject::kMaximumLevelsEditableByUsers];
|
||||
NSString * errorMessage =
|
||||
[NSString stringWithFormat:L(@"error_enter_correct_storey_number"),
|
||||
[NSString stringWithFormat:L(@"editor_storey_number"), osm::EditableMapObject::kMaximumLevelsEditableByUsers];
|
||||
NSString * errorMessage = [NSString stringWithFormat:L(@"error_enter_correct_storey_number"),
|
||||
osm::EditableMapObject::kMaximumLevelsEditableByUsers];
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
@@ -620,8 +615,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
case MetadataID::FMD_LEVEL:
|
||||
{
|
||||
/// @todo Is it ok to use the same error string as in building levels?
|
||||
NSString * errorMessage =
|
||||
[NSString stringWithFormat:L(@"error_enter_correct_storey_number"),
|
||||
NSString * errorMessage = [NSString stringWithFormat:L(@"error_enter_correct_storey_number"),
|
||||
osm::EditableMapObject::kMaximumLevelsEditableByUsers];
|
||||
|
||||
[self configTextViewCell:cell
|
||||
@@ -648,7 +642,8 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
[tCell configWithDelegate:self
|
||||
icon:[UIImage imageNamed:@"ic_placepage_drive_through"]
|
||||
text:L(@"drive_through")
|
||||
value:feature::YesNoUnknownFromString(m_mapObject.GetMetadata(feature::Metadata::FMD_DRIVE_THROUGH))];
|
||||
value:feature::YesNoUnknownFromString(
|
||||
m_mapObject.GetMetadata(feature::Metadata::FMD_DRIVE_THROUGH))];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_SELF_SERVICE:
|
||||
@@ -657,7 +652,8 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
[tCell configWithDelegate:self
|
||||
icon:[UIImage imageNamed:@"ic_placepage_self_service"]
|
||||
text:L(@"self_service")
|
||||
value:feature::YesNoUnknownFromString(m_mapObject.GetMetadata(feature::Metadata::FMD_SELF_SERVICE))];
|
||||
value:feature::YesNoUnknownFromString(
|
||||
m_mapObject.GetMetadata(feature::Metadata::FMD_SELF_SERVICE))];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_OUTDOOR_SEATING:
|
||||
@@ -666,79 +662,56 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
[tCell configWithDelegate:self
|
||||
icon:[UIImage imageNamed:@"ic_placepage_outdoor_seating"]
|
||||
text:L(@"outdoor_seating")
|
||||
value:feature::YesNoUnknownFromString(m_mapObject.GetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING))];
|
||||
value:feature::YesNoUnknownFromString(
|
||||
m_mapObject.GetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING))];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_FEDIVERSE:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_fediverse"
|
||||
placeholder:L(@"fediverse")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_fediverse" placeholder:L(@"fediverse")];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_FACEBOOK:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_facebook"
|
||||
placeholder:L(@"facebook")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_facebook" placeholder:L(@"facebook")];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_INSTAGRAM:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_instagram"
|
||||
placeholder:L(@"instagram")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_instagram" placeholder:L(@"instagram")];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_TWITTER:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_twitter"
|
||||
placeholder:L(@"twitter")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_twitter" placeholder:L(@"twitter")];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_VK:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_vk"
|
||||
placeholder:L(@"vk")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_vk" placeholder:L(@"vk")];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_LINE:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_line"
|
||||
placeholder:L(@"line")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_line" placeholder:L(@"line")];
|
||||
break;
|
||||
}
|
||||
case MetadataID::FMD_CONTACT_BLUESKY:
|
||||
{
|
||||
[self configTextViewCell:cell
|
||||
cellID:cellID
|
||||
icon:@"ic_placepage_bluesky"
|
||||
placeholder:L(@"bluesky")];
|
||||
[self configTextViewCell:cell cellID:cellID icon:@"ic_placepage_bluesky" placeholder:L(@"bluesky")];
|
||||
break;
|
||||
}
|
||||
case MWMEditorCellTypeNote:
|
||||
{
|
||||
MWMNoteCell * tCell = static_cast<MWMNoteCell *>(cell);
|
||||
[tCell configWithDelegate:self
|
||||
noteText:self.note
|
||||
placeholder:L(@"editor_detailed_description_hint")];
|
||||
[tCell configWithDelegate:self noteText:self.note placeholder:L(@"editor_detailed_description_hint")];
|
||||
break;
|
||||
}
|
||||
case MWMEditorCellTypeReportButton:
|
||||
{
|
||||
MWMButtonCell * tCell = static_cast<MWMButtonCell *>(cell);
|
||||
|
||||
auto title = ^NSString *(FeatureStatus s, BOOL isUploaded)
|
||||
{
|
||||
auto title = ^NSString *(FeatureStatus s, BOOL isUploaded) {
|
||||
if (isUploaded)
|
||||
return L(@"editor_place_doesnt_exist");
|
||||
switch (s)
|
||||
@@ -756,9 +729,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
[tCell configureWithDelegate:self title:title(self.featureStatus, self.isFeatureUploaded) enabled:YES];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NSAssert(false, @"Invalid field for editor: %d", (int)cellID);
|
||||
break;
|
||||
default: NSAssert(false, @"Invalid field for editor: %d", (int)cellID); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,8 +756,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (CGFloat)tableView:(UITableView * _Nonnull)tableView
|
||||
heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
- (CGFloat)tableView:(UITableView * _Nonnull)tableView heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
{
|
||||
Class cls = [self cellClassForIndexPath:indexPath];
|
||||
auto cell = [self offscreenCellForClass:cls];
|
||||
@@ -861,8 +831,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
{
|
||||
switch (m_sections[section])
|
||||
{
|
||||
case MWMEditorSectionAddress:
|
||||
return 1.0;
|
||||
case MWMEditorSectionAddress: return 1.0;
|
||||
case MWMEditorSectionDetails:
|
||||
if (find(m_sections.begin(), m_sections.end(), MWMEditorSectionNote) == m_sections.end())
|
||||
return self.notesFooter.height;
|
||||
@@ -876,10 +845,22 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
|
||||
#pragma mark - MWMPlacePageOpeningHoursCellProtocol
|
||||
|
||||
- (BOOL)forcedButton { return YES; }
|
||||
- (BOOL)isPlaceholder { return m_mapObject.GetOpeningHours().empty(); }
|
||||
- (BOOL)isEditor { return YES; }
|
||||
- (BOOL)openingHoursCellExpanded { return YES; }
|
||||
- (BOOL)forcedButton
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
- (BOOL)isPlaceholder
|
||||
{
|
||||
return m_mapObject.GetOpeningHours().empty();
|
||||
}
|
||||
- (BOOL)isEditor
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
- (BOOL)openingHoursCellExpanded
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
- (void)setOpeningHoursCellExpanded:(BOOL)openingHoursCellExpanded
|
||||
{
|
||||
[self performSegueWithIdentifier:kOpeningHoursEditorSegue sender:nil];
|
||||
@@ -890,8 +871,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
if (![self.invalidCells containsObject:indexPath])
|
||||
[self.invalidCells addObject:indexPath];
|
||||
|
||||
[self.tableView reloadRowsAtIndexPaths:@[ indexPath ]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
|
||||
#pragma mark - MWMNoteCellDelegate
|
||||
@@ -908,7 +888,10 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
});
|
||||
}
|
||||
|
||||
- (void)cell:(MWMNoteCell *)cell didFinishEditingWithText:(NSString *)text { self.note = text; }
|
||||
- (void)cell:(MWMNoteCell *)cell didFinishEditingWithText:(NSString *)text
|
||||
{
|
||||
self.note = text;
|
||||
}
|
||||
#pragma mark - MWMEditorAdditionalName
|
||||
|
||||
- (void)editAdditionalNameLanguage:(NSInteger)selectedLangCode
|
||||
@@ -922,16 +905,13 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
{
|
||||
m_newAdditionalLanguages.push_back(languageIndex);
|
||||
self.showAdditionalNames = YES;
|
||||
auto additionalNamesSectionIt =
|
||||
find(m_sections.begin(), m_sections.end(), MWMEditorSectionAdditionalNames);
|
||||
auto additionalNamesSectionIt = find(m_sections.begin(), m_sections.end(), MWMEditorSectionAdditionalNames);
|
||||
assert(additionalNamesSectionIt != m_sections.end());
|
||||
auto const section = distance(m_sections.begin(), additionalNamesSectionIt);
|
||||
NSInteger const row = [self tableView:self.tableView numberOfRowsInSection:section];
|
||||
assert(row > 0);
|
||||
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:row - 1 inSection:section];
|
||||
[self.tableView scrollToRowAtIndexPath:indexPath
|
||||
atScrollPosition:UITableViewScrollPositionMiddle
|
||||
animated:NO];
|
||||
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
|
||||
}
|
||||
|
||||
#pragma mark - MWMEditorCellProtocol
|
||||
@@ -994,45 +974,27 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
case MetadataID::FMD_DRIVE_THROUGH:
|
||||
switch (changeSegmented)
|
||||
{
|
||||
case Yes:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_DRIVE_THROUGH, "yes");
|
||||
break;
|
||||
case No:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_DRIVE_THROUGH, "no");
|
||||
break;
|
||||
case Unknown:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_DRIVE_THROUGH, "");
|
||||
break;
|
||||
case Yes: m_mapObject.SetMetadata(feature::Metadata::FMD_DRIVE_THROUGH, "yes"); break;
|
||||
case No: m_mapObject.SetMetadata(feature::Metadata::FMD_DRIVE_THROUGH, "no"); break;
|
||||
case Unknown: m_mapObject.SetMetadata(feature::Metadata::FMD_DRIVE_THROUGH, ""); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MetadataID::FMD_SELF_SERVICE:
|
||||
switch (changeSegmented)
|
||||
{
|
||||
case Yes:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_SELF_SERVICE, "yes");
|
||||
break;
|
||||
case No:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_SELF_SERVICE, "no");
|
||||
break;
|
||||
case Unknown:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_SELF_SERVICE, "");
|
||||
break;
|
||||
case Yes: m_mapObject.SetMetadata(feature::Metadata::FMD_SELF_SERVICE, "yes"); break;
|
||||
case No: m_mapObject.SetMetadata(feature::Metadata::FMD_SELF_SERVICE, "no"); break;
|
||||
case Unknown: m_mapObject.SetMetadata(feature::Metadata::FMD_SELF_SERVICE, ""); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MetadataID::FMD_OUTDOOR_SEATING:
|
||||
switch (changeSegmented)
|
||||
{
|
||||
case Yes:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING, "yes");
|
||||
break;
|
||||
case No:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING, "no");
|
||||
break;
|
||||
case Unknown:
|
||||
m_mapObject.SetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING, "");
|
||||
break;
|
||||
case Yes: m_mapObject.SetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING, "yes"); break;
|
||||
case No: m_mapObject.SetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING, "no"); break;
|
||||
case Unknown: m_mapObject.SetMetadata(feature::Metadata::FMD_OUTDOOR_SEATING, ""); break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1047,15 +1009,9 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
NSIndexPath * indexPath = [self.tableView indexPathForCell:cell];
|
||||
switch ([self cellTypeForIndexPath:indexPath])
|
||||
{
|
||||
case MWMEditorCellTypeStreet:
|
||||
[self performSegueWithIdentifier:kStreetEditorSegue sender:nil];
|
||||
break;
|
||||
case MetadataID::FMD_CUISINE:
|
||||
[self performSegueWithIdentifier:kCuisineEditorSegue sender:nil];
|
||||
break;
|
||||
case MWMEditorCellTypeCategory:
|
||||
[self performSegueWithIdentifier:kCategoryEditorSegue sender:nil];
|
||||
break;
|
||||
case MWMEditorCellTypeStreet: [self performSegueWithIdentifier:kStreetEditorSegue sender:nil]; break;
|
||||
case MetadataID::FMD_CUISINE: [self performSegueWithIdentifier:kCuisineEditorSegue sender:nil]; break;
|
||||
case MWMEditorCellTypeCategory: [self performSegueWithIdentifier:kCategoryEditorSegue sender:nil]; break;
|
||||
case MWMEditorCellTypeReportButton: [self tapOnButtonCell:cell]; break;
|
||||
default: NSAssert(false, @"Invalid field for cellSelect"); break;
|
||||
}
|
||||
@@ -1071,8 +1027,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
auto placeDoesntExistAction = ^{
|
||||
[self.alertController presentPlaceDoesntExistAlertWithBlock:^(NSString * additionalMessage) {
|
||||
std::string const additional = additionalMessage.length ? additionalMessage.UTF8String : "";
|
||||
GetFramework().CreateNote(self->m_mapObject, osm::Editor::NoteProblemType::PlaceDoesNotExist,
|
||||
additional);
|
||||
GetFramework().CreateNote(self->m_mapObject, osm::Editor::NoteProblemType::PlaceDoesNotExist, additional);
|
||||
[self goBack];
|
||||
[self showNotesQueuedToast];
|
||||
}];
|
||||
@@ -1098,16 +1053,12 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
case FeatureStatus::Untouched: placeDoesntExistAction(); break;
|
||||
case FeatureStatus::Modified:
|
||||
{
|
||||
[self.alertController presentResetChangesAlertWithBlock:^{
|
||||
revertAction(NO);
|
||||
}];
|
||||
[self.alertController presentResetChangesAlertWithBlock:^{ revertAction(NO); }];
|
||||
break;
|
||||
}
|
||||
case FeatureStatus::Created:
|
||||
{
|
||||
[self.alertController presentDeleteFeatureAlertWithBlock:^{
|
||||
revertAction(YES);
|
||||
}];
|
||||
[self.alertController presentDeleteFeatureAlertWithBlock:^{ revertAction(YES); }];
|
||||
break;
|
||||
}
|
||||
case FeatureStatus::Deleted: break;
|
||||
@@ -1133,13 +1084,28 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
|
||||
#pragma mark - MWMCuisineEditorProtocol
|
||||
|
||||
- (std::vector<std::string>)selectedCuisines { return m_mapObject.GetCuisines(); }
|
||||
- (void)setSelectedCuisines:(std::vector<std::string> const &)cuisines { m_mapObject.SetCuisines(cuisines); }
|
||||
- (std::vector<std::string>)selectedCuisines
|
||||
{
|
||||
return m_mapObject.GetCuisines();
|
||||
}
|
||||
- (void)setSelectedCuisines:(std::vector<std::string> const &)cuisines
|
||||
{
|
||||
m_mapObject.SetCuisines(cuisines);
|
||||
}
|
||||
#pragma mark - MWMStreetEditorProtocol
|
||||
|
||||
- (void)setNearbyStreet:(osm::LocalizedStreet const &)street { m_mapObject.SetStreet(street); }
|
||||
- (osm::LocalizedStreet const &)currentStreet { return m_mapObject.GetStreet(); }
|
||||
- (std::vector<osm::LocalizedStreet> const &)nearbyStreets { return m_mapObject.GetNearbyStreets(); }
|
||||
- (void)setNearbyStreet:(osm::LocalizedStreet const &)street
|
||||
{
|
||||
m_mapObject.SetStreet(street);
|
||||
}
|
||||
- (osm::LocalizedStreet const &)currentStreet
|
||||
{
|
||||
return m_mapObject.GetStreet();
|
||||
}
|
||||
- (std::vector<osm::LocalizedStreet> const &)nearbyStreets
|
||||
{
|
||||
return m_mapObject.GetNearbyStreets();
|
||||
}
|
||||
#pragma mark - Segue
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
||||
@@ -1173,7 +1139,9 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
else if ([segue.identifier isEqualToString:kAdditionalNamesEditorSegue])
|
||||
{
|
||||
MWMEditorAdditionalNamesTableViewController * dvc = segue.destinationViewController;
|
||||
[dvc configWithDelegate:self name:m_mapObject.GetNameMultilang() additionalSkipLanguageCodes:m_newAdditionalLanguages];
|
||||
[dvc configWithDelegate:self
|
||||
name:m_mapObject.GetNameMultilang()
|
||||
additionalSkipLanguageCodes:m_newAdditionalLanguages];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1185,8 +1153,7 @@ void registerCellsForTableView(std::vector<MWMEditorCellID> const & cells, UITab
|
||||
if ([ud boolForKey:kUDEditorPersonalInfoWarninWasShown])
|
||||
return NO;
|
||||
|
||||
[self.alertController presentPersonalInfoWarningAlertWithBlock:^
|
||||
{
|
||||
[self.alertController presentPersonalInfoWarningAlertWithBlock:^{
|
||||
[ud setBool:YES forKey:kUDEditorPersonalInfoWarninWasShown];
|
||||
[self onSave];
|
||||
}];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "MWMObjectsCategorySelectorController.h"
|
||||
#import "MWMObjectsCategorySelectorDataSource.h"
|
||||
#import "MWMEditorViewController.h"
|
||||
#import "MWMKeyboard.h"
|
||||
#import "MWMObjectsCategorySelectorDataSource.h"
|
||||
#import "MWMTableViewCell.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
@@ -14,10 +14,11 @@ namespace
|
||||
NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
} // namespace
|
||||
|
||||
@interface MWMObjectsCategorySelectorController ()<UISearchBarDelegate, UITableViewDelegate,
|
||||
UITableViewDataSource, MWMKeyboardObserver>
|
||||
{
|
||||
}
|
||||
@interface MWMObjectsCategorySelectorController () <UISearchBarDelegate,
|
||||
UITableViewDelegate,
|
||||
UITableViewDataSource,
|
||||
MWMKeyboardObserver>
|
||||
{}
|
||||
|
||||
@property(weak, nonatomic) IBOutlet UITableView * tableView;
|
||||
@property(weak, nonatomic) IBOutlet UISearchBar * searchBar;
|
||||
@@ -50,8 +51,7 @@ NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
|
||||
- (void)configTable
|
||||
{
|
||||
[self.tableView registerClass:[MWMTableViewCell class]
|
||||
forCellReuseIdentifier:[UITableViewCell className]];
|
||||
[self.tableView registerClass:[MWMTableViewCell class] forCellReuseIdentifier:[UITableViewCell className]];
|
||||
}
|
||||
|
||||
- (void)setSelectedCategory:(std::string const &)type
|
||||
@@ -64,7 +64,10 @@ NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
|
||||
- (void)configNavBar { self.title = L(@"editor_add_select_category"); }
|
||||
- (void)configNavBar
|
||||
{
|
||||
self.title = L(@"editor_add_select_category");
|
||||
}
|
||||
- (void)configSearchBar
|
||||
{
|
||||
self.searchBar.placeholder = L(@"search");
|
||||
@@ -99,25 +102,32 @@ NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
NSDictionary * options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
|
||||
NSError * error = nil;
|
||||
|
||||
NSAttributedString *attributedText =
|
||||
[[NSAttributedString alloc] initWithData:htmlData
|
||||
NSAttributedString * attributedText = [[NSAttributedString alloc] initWithData:htmlData
|
||||
options:options
|
||||
documentAttributes:nil
|
||||
error:&error];
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
LOG(LERROR, ("Error parsing HTML:", error.localizedDescription));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
UIColor * textColor;
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (@available(iOS 13.0, *))
|
||||
{
|
||||
textColor = [[UIColor alloc] initWithDynamicProvider:^UIColor *(UITraitCollection * traitCollection) {
|
||||
return traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? UIColor.whitePrimaryText : UIColor.blackPrimaryText;
|
||||
return traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? UIColor.whitePrimaryText
|
||||
: UIColor.blackPrimaryText;
|
||||
}];
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
textColor = UIColor.blackPrimaryText;
|
||||
}
|
||||
NSMutableAttributedString *mutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:attributedText];
|
||||
[mutableAttributedText addAttributes:@{ NSForegroundColorAttributeName: textColor,
|
||||
NSFontAttributeName: UIFont.regular14}
|
||||
NSMutableAttributedString * mutableAttributedText =
|
||||
[[NSMutableAttributedString alloc] initWithAttributedString:attributedText];
|
||||
[mutableAttributedText
|
||||
addAttributes:@{NSForegroundColorAttributeName: textColor, NSFontAttributeName: UIFont.regular14}
|
||||
range:NSMakeRange(0, mutableAttributedText.length)];
|
||||
subtitleTextView.attributedText = mutableAttributedText;
|
||||
subtitleTextView.textAlignment = NSTextAlignmentCenter;
|
||||
@@ -149,8 +159,7 @@ NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
NSAssert(false, @"incorrect segue");
|
||||
return;
|
||||
}
|
||||
MWMEditorViewController * dest =
|
||||
static_cast<MWMEditorViewController *>(segue.destinationViewController);
|
||||
MWMEditorViewController * dest = static_cast<MWMEditorViewController *>(segue.destinationViewController);
|
||||
dest.isCreating = YES;
|
||||
auto const object = self.createdObject;
|
||||
[dest setEditableMapObject:object];
|
||||
@@ -180,11 +189,9 @@ NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
|
||||
#pragma mark - UITableView
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
auto cell =
|
||||
[tableView dequeueReusableCellWithCellClass:[UITableViewCell class] indexPath:indexPath];
|
||||
auto cell = [tableView dequeueReusableCellWithCellClass:[UITableViewCell class] indexPath:indexPath];
|
||||
cell.textLabel.text = [self.dataSource getTranslation:indexPath.row];
|
||||
auto const type = [self.dataSource getType:indexPath.row];
|
||||
if ([type isEqualToString:self.selectedType])
|
||||
@@ -269,8 +276,14 @@ NSString * const kToEditorSegue = @"CategorySelectorToEditorSegue";
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { [searchBar resignFirstResponder]; }
|
||||
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
|
||||
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
|
||||
{
|
||||
[searchBar resignFirstResponder];
|
||||
}
|
||||
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
|
||||
{
|
||||
return UIBarPositionTopAttached;
|
||||
}
|
||||
- (void)searchBar:(UISearchBar *)searchBar setActiveState:(BOOL)isActiveState
|
||||
{
|
||||
[searchBar setShowsCancelButton:isActiveState animated:YES];
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "platform/localization.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
using Category = std::pair<std::string, osm::NewFeatureCategories::TypeName>;
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
- (void)refresh
|
||||
{
|
||||
NSString * title = [NSString stringWithFormat:@"%@ %@", L(@"editor_time_add"),
|
||||
stringFromOpeningDays([self.model unhandledDays])];
|
||||
NSString * title =
|
||||
[NSString stringWithFormat:@"%@ %@", L(@"editor_time_add"), stringFromOpeningDays([self.model unhandledDays])];
|
||||
[self.addScheduleButton setTitle:title forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,10 @@ BOOL isCompactForCellWidth(CGFloat width)
|
||||
|
||||
@implementation MWMOpeningHoursClosedSpanTableViewCell
|
||||
|
||||
+ (CGFloat)heightForWidth:(CGFloat)width { return isCompactForCellWidth(width) ? 44.0 : 64.0; }
|
||||
+ (CGFloat)heightForWidth:(CGFloat)width
|
||||
{
|
||||
return isCompactForCellWidth(width) ? 44.0 : 64.0;
|
||||
}
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
@@ -92,7 +95,10 @@ BOOL isCompactForCellWidth(CGFloat width)
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (IBAction)cancelTap { [self.section removeClosedTime:self.row]; }
|
||||
- (IBAction)cancelTap
|
||||
{
|
||||
[self.section removeClosedTime:self.row];
|
||||
}
|
||||
- (IBAction)expandTap
|
||||
{
|
||||
if (!self.isVisible)
|
||||
|
||||
@@ -28,10 +28,8 @@ using namespace osmoh;
|
||||
self.firstWeekday = cal.firstWeekday;
|
||||
NSArray<NSString *> * weekdaySymbols = cal.shortStandaloneWeekdaySymbols;
|
||||
for (UILabel * label in self.labels)
|
||||
{
|
||||
label.text = weekdaySymbols[[self tag2SymbolIndex:label.tag]];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)tag2SymbolIndex:(NSUInteger)tag
|
||||
{
|
||||
@@ -59,15 +57,11 @@ using namespace osmoh;
|
||||
[section removeSelectedDay:wd];
|
||||
}
|
||||
for (UIButton * btn in self.buttons)
|
||||
{
|
||||
if (btn.tag == tag)
|
||||
btn.selected = selected;
|
||||
}
|
||||
for (UILabel * label in self.labels)
|
||||
{
|
||||
if (label.tag == tag)
|
||||
label.textColor = (selected ? [UIColor blackPrimaryText] : [UIColor blackHintText]);
|
||||
}
|
||||
for (UIImageView * image in self.images)
|
||||
{
|
||||
if (image.tag == tag)
|
||||
|
||||
@@ -8,12 +8,10 @@
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
- (void)hide
|
||||
{
|
||||
|
||||
@@ -20,8 +20,10 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
@(MWMOpeningHoursEditorAddScheduleCell): [MWMOpeningHoursAddScheduleTableViewCell class],
|
||||
};
|
||||
|
||||
@interface MWMOpeningHoursEditorViewController ()<UITableViewDelegate, UITableViewDataSource,
|
||||
UITextViewDelegate, MWMOpeningHoursModelProtocol>
|
||||
@interface MWMOpeningHoursEditorViewController () <UITableViewDelegate,
|
||||
UITableViewDataSource,
|
||||
UITextViewDelegate,
|
||||
MWMOpeningHoursModelProtocol>
|
||||
|
||||
@property(weak, nonatomic, readwrite) IBOutlet UITableView * tableView;
|
||||
@property(weak, nonatomic, readwrite) IBOutlet UIView * advancedEditor;
|
||||
@@ -74,12 +76,9 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
- (void)configAdvancedEditor
|
||||
{
|
||||
[self.editorView setTextContainerInset:{.top = 12, .left = 10, .bottom = 12, .right = 10}];
|
||||
self.editorView.keyboardAppearance =
|
||||
[UIColor isNightMode] ? UIKeyboardAppearanceDark : UIKeyboardAppearanceDefault;
|
||||
NSString * path =
|
||||
[NSBundle.mainBundle pathForResource:@"opening_hours_how_to_edit" ofType:@"html"];
|
||||
NSString * html =
|
||||
[[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
|
||||
self.editorView.keyboardAppearance = [UIColor isNightMode] ? UIKeyboardAppearanceDark : UIKeyboardAppearanceDefault;
|
||||
NSString * path = [NSBundle.mainBundle pathForResource:@"opening_hours_how_to_edit" ofType:@"html"];
|
||||
NSString * html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
|
||||
NSURL * baseURL = [NSURL fileURLWithPath:path];
|
||||
[self.help loadHTMLString:html baseURL:baseURL];
|
||||
}
|
||||
@@ -92,7 +91,10 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)onCancel { [self.navigationController popViewControllerAnimated:YES]; }
|
||||
- (void)onCancel
|
||||
{
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
- (void)onDone
|
||||
{
|
||||
[self.model storeCachedData];
|
||||
@@ -122,8 +124,7 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
|
||||
#pragma mark - Fill cells with data
|
||||
|
||||
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell
|
||||
atIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
- (void)fillCell:(MWMOpeningHoursTableViewCell * _Nonnull)cell atIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
{
|
||||
if (!self.parentViewController)
|
||||
return;
|
||||
@@ -157,8 +158,7 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (CGFloat)tableView:(UITableView * _Nonnull)tableView
|
||||
heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
- (CGFloat)tableView:(UITableView * _Nonnull)tableView heightForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
{
|
||||
return [self heightForRowAtIndexPath:indexPath];
|
||||
}
|
||||
@@ -182,8 +182,7 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
{
|
||||
_exampleExpanded = exampleExpanded;
|
||||
self.help.hidden = !exampleExpanded;
|
||||
self.examplesButtonBottomOffset.priority =
|
||||
exampleExpanded ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;
|
||||
self.examplesButtonBottomOffset.priority = exampleExpanded ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh;
|
||||
self.exampleValuesSeparator.hidden = !exampleExpanded;
|
||||
self.exampleValuesExpandView.image =
|
||||
[UIImage imageNamed:exampleExpanded ? @"ic_arrow_gray_up" : @"ic_arrow_gray_down"];
|
||||
@@ -193,8 +192,14 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
[self.editorView becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (IBAction)toggleExample { self.exampleExpanded = !self.exampleExpanded; }
|
||||
- (IBAction)toggleMode { self.isSimpleMode = !self.isSimpleMode; }
|
||||
- (IBAction)toggleExample
|
||||
{
|
||||
self.exampleExpanded = !self.exampleExpanded;
|
||||
}
|
||||
- (IBAction)toggleMode
|
||||
{
|
||||
self.isSimpleMode = !self.isSimpleMode;
|
||||
}
|
||||
#pragma mark - UITextViewDelegate
|
||||
|
||||
- (void)textViewDidChange:(UITextView *)textView
|
||||
@@ -214,5 +219,8 @@ extern NSDictionary * const kMWMOpeningHoursEditorTableCells = @{
|
||||
self.toggleModeButton.enabled = self.model.isSimpleModeCapable;
|
||||
}
|
||||
|
||||
- (BOOL)isSimpleMode { return self.model.isSimpleMode; }
|
||||
- (BOOL)isSimpleMode
|
||||
{
|
||||
return self.model.isSimpleMode;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#import <CoreApi/MWMOpeningHoursCommon.h>
|
||||
#import "MWMOpeningHoursModel.h"
|
||||
#import <CoreApi/MWMOpeningHoursCommon.h>
|
||||
|
||||
#include "editor/ui2oh.hpp"
|
||||
|
||||
@@ -37,11 +37,8 @@ using namespace osmoh;
|
||||
|
||||
- (void)refreshSectionsIndexes
|
||||
{
|
||||
[self.sections enumerateObjectsUsingBlock:^(MWMOpeningHoursSection * _Nonnull section,
|
||||
NSUInteger idx, BOOL * _Nonnull stop)
|
||||
{
|
||||
[section refreshIndex:idx];
|
||||
}];
|
||||
[self.sections enumerateObjectsUsingBlock:^(MWMOpeningHoursSection * _Nonnull section, NSUInteger idx,
|
||||
BOOL * _Nonnull stop) { [section refreshIndex:idx]; }];
|
||||
}
|
||||
|
||||
- (void)addSchedule
|
||||
@@ -81,11 +78,9 @@ using namespace osmoh;
|
||||
- (void)updateActiveSection:(NSUInteger)index
|
||||
{
|
||||
for (MWMOpeningHoursSection * section in self.sections)
|
||||
{
|
||||
if (section.index != index)
|
||||
section.selectedRow = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (ui::TimeTableSet::Proxy)timeTableProxy:(NSUInteger)index
|
||||
{
|
||||
|
||||
@@ -44,10 +44,8 @@ using namespace osmoh;
|
||||
{
|
||||
NSUInteger const numberOfRows = self.numberOfRows;
|
||||
for (NSUInteger row = 0; row != numberOfRows; ++row)
|
||||
{
|
||||
if ([self cellKeyForRow:row] == key)
|
||||
return row;
|
||||
}
|
||||
return numberOfRows;
|
||||
}
|
||||
|
||||
@@ -265,10 +263,8 @@ using namespace osmoh;
|
||||
return;
|
||||
}
|
||||
for (MWMOpeningHoursTableViewCell * cell in tableView.visibleCells)
|
||||
{
|
||||
[cell refresh];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)refreshForNewRowCount:(NSUInteger)newRowCount oldRowCount:(NSUInteger)oldRowCount
|
||||
{
|
||||
@@ -284,11 +280,9 @@ using namespace osmoh;
|
||||
[indexes addObject:[NSIndexPath indexPathForRow:row inSection:self.index]];
|
||||
|
||||
if (addRows)
|
||||
[tableView insertRowsAtIndexPaths:indexes
|
||||
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
|
||||
[tableView insertRowsAtIndexPaths:indexes withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
|
||||
else
|
||||
[tableView deleteRowsAtIndexPaths:indexes
|
||||
withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
|
||||
[tableView deleteRowsAtIndexPaths:indexes withRowAnimation:kMWMOpeningHoursEditorRowAnimation];
|
||||
}];
|
||||
[self refresh:NO];
|
||||
}
|
||||
@@ -390,9 +384,7 @@ using namespace osmoh;
|
||||
case MWMOpeningHoursEditorClosedSpanCell:
|
||||
[self setStartTime:self.cachedStartTime endTime:self.cachedEndTime isClosed:YES];
|
||||
break;
|
||||
default:
|
||||
NSAssert(false, @"Invalid case");
|
||||
break;
|
||||
default: NSAssert(false, @"Invalid case"); break;
|
||||
}
|
||||
}
|
||||
self.cachedStartTime = nil;
|
||||
@@ -405,29 +397,23 @@ using namespace osmoh;
|
||||
|
||||
- (void)scrollIntoView
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
UITableView * tableView = self.delegate.tableView;
|
||||
NSUInteger const lastRow = self.numberOfRows - 1;
|
||||
NSIndexPath * path = [NSIndexPath indexPathForRow:lastRow inSection:self.index];
|
||||
[tableView scrollToRowAtIndexPath:path
|
||||
atScrollPosition:UITableViewScrollPositionNone
|
||||
animated:YES];
|
||||
[tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionNone animated:YES];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)scrollToSelection
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self.selectedRow)
|
||||
return;
|
||||
UITableView * tableView = self.delegate.tableView;
|
||||
NSUInteger const timeSelectorRow = self.selectedRow.unsignedIntegerValue + 1;
|
||||
NSIndexPath * path = [NSIndexPath indexPathForRow:timeSelectorRow inSection:self.index];
|
||||
[tableView scrollToRowAtIndexPath:path
|
||||
atScrollPosition:UITableViewScrollPositionNone
|
||||
animated:YES];
|
||||
[tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionNone animated:YES];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -142,28 +142,23 @@
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
|
||||
{
|
||||
UITableViewCell * cell = nil;
|
||||
if (m_streets.empty())
|
||||
{
|
||||
cell = [tableView dequeueReusableCellWithCellClass:[MWMStreetEditorEditTableViewCell class]
|
||||
indexPath:indexPath];
|
||||
cell = [tableView dequeueReusableCellWithCellClass:[MWMStreetEditorEditTableViewCell class] indexPath:indexPath];
|
||||
}
|
||||
else
|
||||
else if (indexPath.section == 0)
|
||||
{
|
||||
if (indexPath.section == 0)
|
||||
{
|
||||
Class cls = m_streets[indexPath.row].m_localizedName.empty()
|
||||
? [UITableViewCell class]
|
||||
: [MWMTableViewSubtitleCell class];
|
||||
Class cls =
|
||||
m_streets[indexPath.row].m_localizedName.empty() ? [UITableViewCell class] : [MWMTableViewSubtitleCell class];
|
||||
cell = [tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath];
|
||||
}
|
||||
else
|
||||
{
|
||||
cell = [tableView dequeueReusableCellWithCellClass:[MWMStreetEditorEditTableViewCell class]
|
||||
indexPath:indexPath];
|
||||
}
|
||||
cell = [tableView dequeueReusableCellWithCellClass:[MWMStreetEditorEditTableViewCell class] indexPath:indexPath];
|
||||
}
|
||||
|
||||
[self fillCell:cell indexPath:indexPath];
|
||||
|
||||
@@ -35,26 +35,20 @@ using WeekDayView = MWMPlacePageOpeningHoursDayView *;
|
||||
|
||||
NSString * stringFromTimeSpan(Timespan const & timeSpan)
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ - %@", stringFromTime(timeSpan.GetStart()),
|
||||
stringFromTime(timeSpan.GetEnd())];
|
||||
return [NSString stringWithFormat:@"%@ - %@", stringFromTime(timeSpan.GetStart()), stringFromTime(timeSpan.GetEnd())];
|
||||
}
|
||||
|
||||
NSArray<NSString *> * arrayFromClosedTimes(TTimespans const & closedTimes)
|
||||
{
|
||||
NSMutableArray<NSString *> * breaks = [NSMutableArray arrayWithCapacity:closedTimes.size()];
|
||||
for (auto & ct : closedTimes)
|
||||
{
|
||||
[breaks addObject:stringFromTimeSpan(ct)];
|
||||
}
|
||||
return [breaks copy];
|
||||
}
|
||||
|
||||
WeekDayView getWeekDayView()
|
||||
{
|
||||
return [NSBundle.mainBundle loadNibNamed:@"MWMPlacePageOpeningHoursWeekDayView"
|
||||
owner:nil
|
||||
options:nil]
|
||||
.firstObject;
|
||||
return [NSBundle.mainBundle loadNibNamed:@"MWMPlacePageOpeningHoursWeekDayView" owner:nil options:nil].firstObject;
|
||||
}
|
||||
|
||||
@implementation MWMPlacePageOpeningHoursCell
|
||||
@@ -100,8 +94,7 @@ WeekDayView getWeekDayView()
|
||||
{
|
||||
NSCalendar * cal = NSCalendar.currentCalendar;
|
||||
cal.locale = NSLocale.currentLocale;
|
||||
Weekday currentDay =
|
||||
static_cast<Weekday>([cal components:NSCalendarUnitWeekday fromDate:[NSDate date]].weekday);
|
||||
Weekday currentDay = static_cast<Weekday>([cal components:NSCalendarUnitWeekday fromDate:[NSDate date]].weekday);
|
||||
BOOL haveCurrentDay = NO;
|
||||
size_t timeTablesCount = timeTableSet.Size();
|
||||
self.haveExpandSchedule = (timeTablesCount > 1 || !timeTableSet.GetUnhandledDays().empty());
|
||||
@@ -255,9 +248,7 @@ WeekDayView getWeekDayView()
|
||||
// Major QA can tap multiple times before first segue call is performed.
|
||||
// This leads to multiple identical controllers to be pushed.
|
||||
self.toggleButton.enabled = NO;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.toggleButton.enabled = YES;
|
||||
});
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ self.toggleButton.enabled = YES; });
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
#import "MWMActivityViewController.h"
|
||||
#import "MWMLocationHelpers.h"
|
||||
#import "MWMLocationObserver.h"
|
||||
#import "MWMMapViewControlsManager+AddPlace.h"
|
||||
#import "MWMRoutePoint+CPP.h"
|
||||
#import "MWMStorage+UI.h"
|
||||
#import "SwiftBridge.h"
|
||||
#import "MWMMapViewControlsManager+AddPlace.h"
|
||||
|
||||
#import <CoreApi/Framework.h>
|
||||
#import <CoreApi/StringUtils.h>
|
||||
@@ -25,42 +25,49 @@ using namespace storage;
|
||||
|
||||
@implementation MWMPlacePageManager
|
||||
|
||||
- (BOOL)isPPShown {
|
||||
- (BOOL)isPPShown
|
||||
{
|
||||
return GetFramework().HasPlacePageInfo();
|
||||
}
|
||||
|
||||
- (void)closePlacePage { GetFramework().DeactivateMapSelection(); }
|
||||
- (void)closePlacePage
|
||||
{
|
||||
GetFramework().DeactivateMapSelection();
|
||||
}
|
||||
|
||||
- (void)routeFrom:(PlacePageData *)data {
|
||||
- (void)routeFrom:(PlacePageData *)data
|
||||
{
|
||||
MWMRoutePoint * point = [self routePoint:data withType:MWMRoutePointTypeStart intermediateIndex:0];
|
||||
[MWMRouter buildFromPoint:point bestRouter:YES];
|
||||
[self closePlacePage];
|
||||
}
|
||||
|
||||
- (void)routeTo:(PlacePageData *)data {
|
||||
if ([MWMRouter isOnRoute]) {
|
||||
- (void)routeTo:(PlacePageData *)data
|
||||
{
|
||||
if ([MWMRouter isOnRoute])
|
||||
[MWMRouter stopRouting];
|
||||
}
|
||||
|
||||
if ([MWMMapOverlayManager transitEnabled]) {
|
||||
if ([MWMMapOverlayManager transitEnabled])
|
||||
[MWMRouter setType:MWMRouterTypePublicTransport];
|
||||
}
|
||||
|
||||
MWMRoutePoint * point = [self routePoint:data withType:MWMRoutePointTypeFinish intermediateIndex:0];
|
||||
[MWMRouter buildToPoint:point bestRouter:YES];
|
||||
[self closePlacePage];
|
||||
}
|
||||
|
||||
- (void)routeAddStop:(PlacePageData *)data {
|
||||
- (void)routeAddStop:(PlacePageData *)data
|
||||
{
|
||||
MWMRoutePoint * point = [self routePoint:data withType:MWMRoutePointTypeIntermediate intermediateIndex:0];
|
||||
[MWMRouter addPointAndRebuild:point];
|
||||
[self closePlacePage];
|
||||
}
|
||||
|
||||
- (void)routeRemoveStop:(PlacePageData *)data {
|
||||
- (void)routeRemoveStop:(PlacePageData *)data
|
||||
{
|
||||
MWMRoutePoint * point = nil;
|
||||
auto const intermediateIndex = GetFramework().GetCurrentPlacePageInfo().GetIntermediateIndex();
|
||||
switch (GetFramework().GetCurrentPlacePageInfo().GetRouteMarkType()) {
|
||||
switch (GetFramework().GetCurrentPlacePageInfo().GetRouteMarkType())
|
||||
{
|
||||
case RouteMarkType::Start:
|
||||
point = [self routePoint:data withType:MWMRoutePointTypeStart intermediateIndex:intermediateIndex];
|
||||
break;
|
||||
@@ -79,27 +86,24 @@ using namespace storage;
|
||||
pointType:(MWMRoutePointType)type
|
||||
intermediateIndex:(size_t)intermediateIndex
|
||||
{
|
||||
if (data.isMyPosition) {
|
||||
if (data.isMyPosition)
|
||||
return [[MWMRoutePoint alloc] initWithLastLocationAndType:type intermediateIndex:intermediateIndex];
|
||||
}
|
||||
|
||||
NSString * title = nil;
|
||||
if (data.previewData.title.length > 0) {
|
||||
if (data.previewData.title.length > 0)
|
||||
title = data.previewData.title;
|
||||
} else if (data.previewData.secondarySubtitle.length > 0) {
|
||||
else if (data.previewData.secondarySubtitle.length > 0)
|
||||
title = data.previewData.secondarySubtitle;
|
||||
} else if (data.previewData.subtitle.length > 0) {
|
||||
else if (data.previewData.subtitle.length > 0)
|
||||
title = data.previewData.subtitle;
|
||||
} else if (data.bookmarkData != nil) {
|
||||
else if (data.bookmarkData != nil)
|
||||
title = data.bookmarkData.externalTitle;
|
||||
} else {
|
||||
else
|
||||
title = L(@"core_placepage_unknown_place");
|
||||
}
|
||||
|
||||
NSString * subtitle = nil;
|
||||
if (data.previewData.subtitle.length > 0 && ![title isEqualToString:data.previewData.subtitle]) {
|
||||
if (data.previewData.subtitle.length > 0 && ![title isEqualToString:data.previewData.subtitle])
|
||||
subtitle = data.previewData.subtitle;
|
||||
}
|
||||
|
||||
return [[MWMRoutePoint alloc] initWithPoint:location_helpers::ToMercator(data.locationCoordinate)
|
||||
title:title
|
||||
@@ -112,28 +116,24 @@ using namespace storage;
|
||||
withType:(MWMRoutePointType)type
|
||||
intermediateIndex:(size_t)intermediateIndex
|
||||
{
|
||||
if (data.isMyPosition) {
|
||||
return [[MWMRoutePoint alloc] initWithLastLocationAndType:type
|
||||
intermediateIndex:intermediateIndex];
|
||||
}
|
||||
if (data.isMyPosition)
|
||||
return [[MWMRoutePoint alloc] initWithLastLocationAndType:type intermediateIndex:intermediateIndex];
|
||||
|
||||
NSString * title = nil;
|
||||
if (data.previewData.title.length > 0) {
|
||||
if (data.previewData.title.length > 0)
|
||||
title = data.previewData.title;
|
||||
} else if (data.previewData.secondarySubtitle.length > 0) {
|
||||
else if (data.previewData.secondarySubtitle.length > 0)
|
||||
title = data.previewData.secondarySubtitle;
|
||||
} else if (data.previewData.subtitle.length > 0) {
|
||||
else if (data.previewData.subtitle.length > 0)
|
||||
title = data.previewData.subtitle;
|
||||
} else if (data.bookmarkData != nil) {
|
||||
else if (data.bookmarkData != nil)
|
||||
title = data.bookmarkData.externalTitle;
|
||||
} else {
|
||||
else
|
||||
title = L(@"core_placepage_unknown_place");
|
||||
}
|
||||
|
||||
NSString * subtitle = nil;
|
||||
if (data.previewData.subtitle.length > 0 && ![title isEqualToString:data.previewData.subtitle]) {
|
||||
if (data.previewData.subtitle.length > 0 && ![title isEqualToString:data.previewData.subtitle])
|
||||
subtitle = data.previewData.subtitle;
|
||||
}
|
||||
|
||||
return [[MWMRoutePoint alloc] initWithPoint:location_helpers::ToMercator(data.locationCoordinate)
|
||||
title:title
|
||||
@@ -158,7 +158,8 @@ using namespace storage;
|
||||
[[MWMMapViewControlsManager manager] addPlace:NO position:&position];
|
||||
}
|
||||
|
||||
- (void)addBookmark:(PlacePageData *)data {
|
||||
- (void)addBookmark:(PlacePageData *)data
|
||||
{
|
||||
auto & f = GetFramework();
|
||||
auto & bmManager = f.GetBookmarkManager();
|
||||
auto & info = f.GetCurrentPlacePageInfo();
|
||||
@@ -167,9 +168,8 @@ using namespace storage;
|
||||
bmData.m_name = info.FormatNewBookmarkName();
|
||||
bmData.m_color.m_predefinedColor = f.LastEditedBMColor();
|
||||
bmData.m_point = info.GetMercator();
|
||||
if (info.IsFeature()) {
|
||||
if (info.IsFeature())
|
||||
SaveFeatureTypes(info.GetTypes(), bmData);
|
||||
}
|
||||
auto editSession = bmManager.GetEditSession();
|
||||
auto const * bookmark = editSession.CreateBookmark(std::move(bmData), categoryId);
|
||||
|
||||
@@ -180,9 +180,14 @@ using namespace storage;
|
||||
[data updateBookmarkStatus];
|
||||
}
|
||||
|
||||
- (void)updateBookmark:(PlacePageData *)data color:(MWMBookmarkColor)color category:(MWMMarkGroupID)category {
|
||||
- (void)updateBookmark:(PlacePageData *)data color:(MWMBookmarkColor)color category:(MWMMarkGroupID)category
|
||||
{
|
||||
MWMBookmarksManager * bookmarksManager = [MWMBookmarksManager sharedManager];
|
||||
[bookmarksManager updateBookmark:data.bookmarkData.bookmarkId setGroupId:category title:data.previewData.title color:color description:data.bookmarkData.bookmarkDescription];
|
||||
[bookmarksManager updateBookmark:data.bookmarkData.bookmarkId
|
||||
setGroupId:category
|
||||
title:data.previewData.title
|
||||
color:color
|
||||
description:data.bookmarkData.bookmarkDescription];
|
||||
[MWMFrameworkHelper updatePlacePageData];
|
||||
[data updateBookmarkStatus];
|
||||
}
|
||||
@@ -195,7 +200,8 @@ using namespace storage;
|
||||
[data updateBookmarkStatus];
|
||||
}
|
||||
|
||||
- (void)updateTrack:(PlacePageData *)data color:(UIColor *)color category:(MWMMarkGroupID)category {
|
||||
- (void)updateTrack:(PlacePageData *)data color:(UIColor *)color category:(MWMMarkGroupID)category
|
||||
{
|
||||
MWMBookmarksManager * bookmarksManager = [MWMBookmarksManager sharedManager];
|
||||
[bookmarksManager updateTrack:data.trackData.trackId setGroupId:category color:color title:data.previewData.title];
|
||||
[MWMFrameworkHelper updatePlacePageData];
|
||||
@@ -208,26 +214,31 @@ using namespace storage;
|
||||
f.GetBookmarkManager().GetEditSession().DeleteTrack(data.trackData.trackId);
|
||||
}
|
||||
|
||||
- (void)call:(PlacePagePhone *)phone {
|
||||
- (void)call:(PlacePagePhone *)phone
|
||||
{
|
||||
NSURL * _Nullable phoneURL = phone.url;
|
||||
if (phoneURL && [UIApplication.sharedApplication canOpenURL:phoneURL]) {
|
||||
if (phoneURL && [UIApplication.sharedApplication canOpenURL:phoneURL])
|
||||
[UIApplication.sharedApplication openURL:phoneURL options:@{} completionHandler:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)editBookmark:(PlacePageData *)data {
|
||||
MWMEditBookmarkController *editBookmarkController = [[UIStoryboard instance:MWMStoryboardMain]
|
||||
instantiateViewControllerWithIdentifier:@"MWMEditBookmarkController"];
|
||||
- (void)editBookmark:(PlacePageData *)data
|
||||
{
|
||||
MWMEditBookmarkController * editBookmarkController =
|
||||
[[UIStoryboard instance:MWMStoryboardMain] instantiateViewControllerWithIdentifier:@"MWMEditBookmarkController"];
|
||||
[editBookmarkController configureWithPlacePageData:data];
|
||||
[[MapViewController sharedController].navigationController pushViewController:editBookmarkController animated:YES];
|
||||
}
|
||||
|
||||
- (void)editTrack:(PlacePageData *)data {
|
||||
if (data.objectType != PlacePageObjectTypeTrack) {
|
||||
- (void)editTrack:(PlacePageData *)data
|
||||
{
|
||||
if (data.objectType != PlacePageObjectTypeTrack)
|
||||
{
|
||||
ASSERT_FAIL("editTrack called for non-track object");
|
||||
return;
|
||||
}
|
||||
EditTrackViewController * editTrackController = [[EditTrackViewController alloc] initWithTrackId:data.trackData.trackId editCompletion:^(BOOL edited) {
|
||||
EditTrackViewController * editTrackController =
|
||||
[[EditTrackViewController alloc] initWithTrackId:data.trackData.trackId
|
||||
editCompletion:^(BOOL edited) {
|
||||
if (!edited)
|
||||
return;
|
||||
[MWMFrameworkHelper updatePlacePageData];
|
||||
@@ -241,82 +252,107 @@ using namespace storage;
|
||||
[self.ownerViewController openFullPlaceDescriptionWithHtml:htmlString];
|
||||
}
|
||||
|
||||
- (void)avoidDirty {
|
||||
- (void)avoidDirty
|
||||
{
|
||||
[MWMRouter avoidRoadTypeAndRebuild:MWMRoadTypeDirty];
|
||||
[self closePlacePage];
|
||||
}
|
||||
|
||||
- (void)avoidFerry {
|
||||
- (void)avoidFerry
|
||||
{
|
||||
[MWMRouter avoidRoadTypeAndRebuild:MWMRoadTypeFerry];
|
||||
[self closePlacePage];
|
||||
}
|
||||
|
||||
- (void)avoidToll {
|
||||
- (void)avoidToll
|
||||
{
|
||||
[MWMRouter avoidRoadTypeAndRebuild:MWMRoadTypeToll];
|
||||
[self closePlacePage];
|
||||
}
|
||||
|
||||
- (void)openWebsite:(PlacePageData *)data {
|
||||
- (void)openWebsite:(PlacePageData *)data
|
||||
{
|
||||
[self.ownerViewController openUrl:data.infoData.website externally:YES];
|
||||
}
|
||||
|
||||
- (void)openWebsiteMenu:(PlacePageData *)data {
|
||||
- (void)openWebsiteMenu:(PlacePageData *)data
|
||||
{
|
||||
[self.ownerViewController openUrl:data.infoData.websiteMenu externally:YES];
|
||||
}
|
||||
|
||||
- (void)openWikipedia:(PlacePageData *)data {
|
||||
- (void)openWikipedia:(PlacePageData *)data
|
||||
{
|
||||
[self.ownerViewController openUrl:data.infoData.wikipedia externally:YES];
|
||||
}
|
||||
|
||||
- (void)openWikimediaCommons:(PlacePageData *)data {
|
||||
- (void)openWikimediaCommons:(PlacePageData *)data
|
||||
{
|
||||
[self.ownerViewController openUrl:data.infoData.wikimediaCommons externally:YES];
|
||||
}
|
||||
|
||||
- (void)openFediverse:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_FEDIVERSE, [data.infoData.fediverse UTF8String]);
|
||||
- (void)openFediverse:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_FEDIVERSE, [data.infoData.fediverse UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openFacebook:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_FACEBOOK, [data.infoData.facebook UTF8String]);
|
||||
- (void)openFacebook:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_FACEBOOK, [data.infoData.facebook UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openInstagram:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_INSTAGRAM, [data.infoData.instagram UTF8String]);
|
||||
- (void)openInstagram:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_INSTAGRAM, [data.infoData.instagram UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openTwitter:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_TWITTER, [data.infoData.twitter UTF8String]);
|
||||
- (void)openTwitter:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_TWITTER, [data.infoData.twitter UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openVk:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_VK, [data.infoData.vk UTF8String]);
|
||||
- (void)openVk:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_VK, [data.infoData.vk UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openLine:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_LINE, [data.infoData.line UTF8String]);
|
||||
- (void)openLine:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_LINE, [data.infoData.line UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openBluesky:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_BLUESKY, [data.infoData.bluesky UTF8String]);
|
||||
- (void)openBluesky:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_BLUESKY, [data.infoData.bluesky UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openPanoramax:(PlacePageData *)data {
|
||||
std::string const fullUrl = osm::socialContactToURL(osm::MapObject::MetadataID::FMD_PANORAMAX, [data.infoData.panoramax UTF8String]);
|
||||
- (void)openPanoramax:(PlacePageData *)data
|
||||
{
|
||||
std::string const fullUrl =
|
||||
osm::socialContactToURL(osm::MapObject::MetadataID::FMD_PANORAMAX, [data.infoData.panoramax UTF8String]);
|
||||
[self.ownerViewController openUrl:ToNSString(fullUrl) externally:YES];
|
||||
}
|
||||
|
||||
- (void)openEmail:(PlacePageData *)data {
|
||||
- (void)openEmail:(PlacePageData *)data
|
||||
{
|
||||
[MailComposer sendEmailWithSubject:nil body:nil toRecipients:@[data.infoData.email] attachmentFileURL:nil];
|
||||
}
|
||||
|
||||
- (void)openElevationDifficultPopup:(PlacePageData *)data {
|
||||
- (void)openElevationDifficultPopup:(PlacePageData *)data
|
||||
{
|
||||
auto difficultyPopup = [ElevationDetailsBuilder buildWithData:data];
|
||||
[[MapViewController sharedController] presentViewController:difficultyPopup animated:YES completion:nil];
|
||||
}
|
||||
@@ -332,8 +368,14 @@ using namespace storage;
|
||||
|
||||
#pragma mark - MWMFeatureHolder
|
||||
|
||||
- (FeatureID const &)featureId { return GetFramework().GetCurrentPlacePageInfo().GetID(); }
|
||||
- (FeatureID const &)featureId
|
||||
{
|
||||
return GetFramework().GetCurrentPlacePageInfo().GetID();
|
||||
}
|
||||
|
||||
- (MapViewController *)ownerViewController { return [MapViewController sharedController]; }
|
||||
- (MapViewController *)ownerViewController
|
||||
{
|
||||
return [MapViewController sharedController];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -62,167 +62,208 @@
|
||||
[[MWMMapViewControlsManager manager].placePageManager updateAvailableArea:frame];
|
||||
}
|
||||
|
||||
+ (void)editPlace {
|
||||
+ (void)editPlace
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager editPlace];
|
||||
}
|
||||
|
||||
+ (void)addBusiness {
|
||||
+ (void)addBusiness
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager addBusiness];
|
||||
}
|
||||
|
||||
+ (void)addPlace:(CLLocationCoordinate2D)coordinate {
|
||||
+ (void)addPlace:(CLLocationCoordinate2D)coordinate
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager addPlace:coordinate];
|
||||
}
|
||||
|
||||
+ (void)openWebsite:(PlacePageData *)data {
|
||||
+ (void)openWebsite:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openWebsite:data];
|
||||
}
|
||||
|
||||
+ (void)openWebsiteMenu:(PlacePageData *)data {
|
||||
+ (void)openWebsiteMenu:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openWebsiteMenu:data];
|
||||
}
|
||||
|
||||
+ (void)openEmail:(PlacePageData *)data {
|
||||
+ (void)openEmail:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openEmail:data];
|
||||
}
|
||||
|
||||
+ (void)openWikipedia:(PlacePageData *)data {
|
||||
+ (void)openWikipedia:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openWikipedia:data];
|
||||
}
|
||||
|
||||
+ (void)openWikimediaCommons:(PlacePageData *)data {
|
||||
+ (void)openWikimediaCommons:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openWikimediaCommons:data];
|
||||
}
|
||||
|
||||
+ (void)openFediverse:(PlacePageData *)data {
|
||||
+ (void)openFediverse:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openFediverse:data];
|
||||
}
|
||||
|
||||
+ (void)openFacebook:(PlacePageData *)data {
|
||||
+ (void)openFacebook:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openFacebook:data];
|
||||
}
|
||||
|
||||
+ (void)openInstagram:(PlacePageData *)data {
|
||||
+ (void)openInstagram:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openInstagram:data];
|
||||
}
|
||||
|
||||
+ (void)openTwitter:(PlacePageData *)data {
|
||||
+ (void)openTwitter:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openTwitter:data];
|
||||
}
|
||||
|
||||
+ (void)openVk:(PlacePageData *)data {
|
||||
+ (void)openVk:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openVk:data];
|
||||
}
|
||||
|
||||
+ (void)openLine:(PlacePageData *)data {
|
||||
+ (void)openLine:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openLine:data];
|
||||
}
|
||||
|
||||
+ (void)openBluesky:(PlacePageData *)data {
|
||||
+ (void)openBluesky:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openBluesky:data];
|
||||
}
|
||||
|
||||
+ (void)openPanoramax:(PlacePageData *)data {
|
||||
+ (void)openPanoramax:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openPanoramax:data];
|
||||
}
|
||||
|
||||
+ (void)call:(PlacePagePhone *)phone {
|
||||
+ (void)call:(PlacePagePhone *)phone
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager call:phone];
|
||||
}
|
||||
|
||||
+ (void)showAllFacilities:(PlacePageData *)data {
|
||||
+ (void)showAllFacilities:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager showAllFacilities:data];
|
||||
}
|
||||
|
||||
+ (void)showPlaceDescription:(NSString *)htmlString {
|
||||
+ (void)showPlaceDescription:(NSString *)htmlString
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager showPlaceDescription:htmlString];
|
||||
}
|
||||
|
||||
+ (void)openMoreUrl:(PlacePageData *)data {
|
||||
+ (void)openMoreUrl:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openMoreUrl:data];
|
||||
}
|
||||
|
||||
+ (void)openReviewUrl:(PlacePageData *)data {
|
||||
+ (void)openReviewUrl:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openReviewUrl:data];
|
||||
}
|
||||
|
||||
+ (void)openDescriptionUrl:(PlacePageData *)data {
|
||||
+ (void)openDescriptionUrl:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openDescriptionUrl:data];
|
||||
}
|
||||
|
||||
+ (void)openCatalogSingleItem:(PlacePageData *)data atIndex:(NSInteger)index {
|
||||
+ (void)openCatalogSingleItem:(PlacePageData *)data atIndex:(NSInteger)index
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openCatalogSingleItem:data atIndex:index];
|
||||
}
|
||||
|
||||
+ (void)openCatalogMoreItems:(PlacePageData *)data {
|
||||
+ (void)openCatalogMoreItems:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openCatalogMoreItems:data];
|
||||
}
|
||||
|
||||
+ (void)addBookmark:(PlacePageData *)data {
|
||||
+ (void)addBookmark:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager addBookmark:data];
|
||||
}
|
||||
|
||||
+ (void)updateBookmark:(PlacePageData *)data color:(MWMBookmarkColor)color category:(MWMMarkGroupID)category {
|
||||
+ (void)updateBookmark:(PlacePageData *)data color:(MWMBookmarkColor)color category:(MWMMarkGroupID)category
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager updateBookmark:data color:color category:category];
|
||||
}
|
||||
|
||||
+ (void)removeBookmark:(PlacePageData *)data {
|
||||
+ (void)removeBookmark:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager removeBookmark:data];
|
||||
}
|
||||
|
||||
+ (void)updateTrack:(PlacePageData *)data color:(UIColor *)color category:(MWMMarkGroupID)category {
|
||||
+ (void)updateTrack:(PlacePageData *)data color:(UIColor *)color category:(MWMMarkGroupID)category
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager updateTrack:data color:color category:category];
|
||||
}
|
||||
|
||||
+ (void)removeTrack:(PlacePageData *)data {
|
||||
+ (void)removeTrack:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager removeTrack:data];
|
||||
}
|
||||
|
||||
+ (void)editBookmark:(PlacePageData *)data {
|
||||
+ (void)editBookmark:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager editBookmark:data];
|
||||
}
|
||||
|
||||
+ (void)editTrack:(PlacePageData *)data {
|
||||
+ (void)editTrack:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager editTrack:data];
|
||||
}
|
||||
|
||||
+ (void)searchBookingHotels:(PlacePageData *)data {
|
||||
+ (void)searchBookingHotels:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager searchBookingHotels:data];
|
||||
}
|
||||
|
||||
+ (void)book:(PlacePageData *)data {
|
||||
+ (void)book:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager book:data];
|
||||
}
|
||||
|
||||
+ (void)routeFrom:(PlacePageData *)data {
|
||||
+ (void)routeFrom:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager routeFrom:data];
|
||||
}
|
||||
|
||||
+ (void)routeTo:(PlacePageData *)data {
|
||||
+ (void)routeTo:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager routeTo:data];
|
||||
}
|
||||
|
||||
+ (void)routeAddStop:(PlacePageData *)data {
|
||||
+ (void)routeAddStop:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager routeAddStop:data];
|
||||
}
|
||||
|
||||
+ (void)routeRemoveStop:(PlacePageData *)data {
|
||||
+ (void)routeRemoveStop:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager routeRemoveStop:data];
|
||||
}
|
||||
|
||||
+ (void)avoidDirty {
|
||||
+ (void)avoidDirty
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager avoidDirty];
|
||||
}
|
||||
|
||||
+ (void)avoidFerry {
|
||||
+ (void)avoidFerry
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager avoidFerry];
|
||||
}
|
||||
|
||||
+ (void)avoidToll {
|
||||
+ (void)avoidToll
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager avoidToll];
|
||||
}
|
||||
|
||||
+ (void)openElevationDifficultPopup:(PlacePageData *)data {
|
||||
+ (void)openElevationDifficultPopup:(PlacePageData *)data
|
||||
{
|
||||
[[MWMMapViewControlsManager manager].placePageManager openElevationDifficultPopup:data];
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
@implementation MWMSearchCell
|
||||
|
||||
- (void)configureWith:(SearchResult * _Nonnull)result isPartialMatching:(BOOL)isPartialMatching {
|
||||
- (void)configureWith:(SearchResult * _Nonnull)result isPartialMatching:(BOOL)isPartialMatching
|
||||
{
|
||||
NSString * title = result.titleText;
|
||||
|
||||
if (title.length == 0)
|
||||
@@ -25,21 +26,20 @@
|
||||
self.titleLabel.text = title;
|
||||
return;
|
||||
}
|
||||
NSMutableAttributedString * attributedTitle =
|
||||
[[NSMutableAttributedString alloc] initWithString:title];
|
||||
NSMutableAttributedString * attributedTitle = [[NSMutableAttributedString alloc] initWithString:title];
|
||||
NSDictionary * titleAttributes = isPartialMatching ? unselectedTitleAttributes : selectedTitleAttributes;
|
||||
|
||||
NSArray<NSValue *> * highlightRanges = result.highlightRanges;
|
||||
[attributedTitle addAttributes:titleAttributes range:NSMakeRange(0, title.length)];
|
||||
|
||||
for (NSValue *rangeValue in highlightRanges) {
|
||||
for (NSValue * rangeValue in highlightRanges)
|
||||
{
|
||||
NSRange range = [rangeValue rangeValue];
|
||||
if (NSMaxRange(range) <= result.titleText.length) {
|
||||
if (NSMaxRange(range) <= result.titleText.length)
|
||||
[attributedTitle addAttributes:selectedTitleAttributes range:range];
|
||||
} else {
|
||||
else
|
||||
NSLog(@"Incorrect range: %@ for string: %@", NSStringFromRange(range), result.titleText);
|
||||
}
|
||||
}
|
||||
self.titleLabel.attributedText = attributedTitle;
|
||||
[self.titleLabel sizeToFit];
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user