BathyScapheの中身をぐちゃぐちゃに
Révision | 75d200361f3cb61974c790b3be25250aae9628e4 (tree) |
---|---|
l'heure | 2012-07-02 23:03:57 |
Auteur | masakih <masakih@user...> |
Commiter | masakih |
[Mod] KMLinkHanlderを使用するように変更
@@ -9,6 +9,7 @@ | ||
9 | 9 | #import <Foundation/Foundation.h> |
10 | 10 | |
11 | 11 | @class KMDocument; |
12 | +@class KMLinkHanlder; | |
12 | 13 | |
13 | 14 | @protocol KMBSLogPopUpOwner; |
14 | 15 |
@@ -41,7 +42,7 @@ | ||
41 | 42 | @end |
42 | 43 | |
43 | 44 | @protocol KMBSLogPopUpOwner <NSObject> |
44 | -- (BOOL)isMessageLink:(id)aLink messageIndexes:(NSIndexSet **)indexesPtr; | |
45 | +- (KMLinkHanlder *)linkHandler; | |
45 | 46 | |
46 | 47 | - (NSUInteger)numberOfMessage; |
47 | 48 | @end |
@@ -10,6 +10,7 @@ | ||
10 | 10 | |
11 | 11 | #import "KMDocument.h" |
12 | 12 | #import "KMBSLogViewController.h" |
13 | +#import "KMLinkHanlder.h" | |
13 | 14 | |
14 | 15 | #import "AppDefaults.h" |
15 | 16 | #import "CMRAttributedMessageComposer.h" |
@@ -159,7 +160,7 @@ if (kSpamFilterInvisibleAbonedBehavior == [CMRPref spamFilterBehavior]) { | ||
159 | 160 | NSIndexSet *indexes; |
160 | 161 | NSAttributedString *message_; |
161 | 162 | |
162 | - if (![self.owner isMessageLink:aLink messageIndexes:&indexes]) { | |
163 | + if (![self.owner.linkHandler isMessageLink:aLink messageIndexes:&indexes]) { | |
163 | 164 | goto ErrInvalidLink; |
164 | 165 | } |
165 | 166 | message_ = [self contentsForIndexes:indexes]; |
@@ -9,6 +9,8 @@ | ||
9 | 9 | #import "KMLogViewController.h" |
10 | 10 | #import "KMDocument.h" |
11 | 11 | |
12 | +#import "KMLinkHanlder.h" | |
13 | + | |
12 | 14 | @class KMWorkerEmulator; |
13 | 15 | @class KMStatusLineViewController; |
14 | 16 |
@@ -44,6 +46,7 @@ | ||
44 | 46 | KMHistoryStack *_histories; |
45 | 47 | KMBSLogViewDelegate *_logViewDelegate; |
46 | 48 | KMBSLogPopUp *_popUp; |
49 | + KMLinkHanlder *_linkHandler; | |
47 | 50 | #endif |
48 | 51 | } |
49 | 52 | @property (nonatomic, retain) KMStatusLineViewController *statusLine; |
@@ -59,6 +62,9 @@ | ||
59 | 62 | |
60 | 63 | @property BOOL hasTitleRuler; |
61 | 64 | |
65 | + | |
66 | +@property (nonatomic, retain, readonly) KMLinkHanlder *linkHandler; | |
67 | + | |
62 | 68 | - (void)scrollMessageAtIndex:(NSUInteger)index; |
63 | 69 | @end |
64 | 70 |
@@ -59,6 +59,7 @@ NSString *const BSThreadViewerDidEndFindingNotification = @"BSThreadViewerDidEnd | ||
59 | 59 | @property (nonatomic, retain) KMHistoryStack *histories; |
60 | 60 | @property (nonatomic, retain) KMBSLogViewDelegate *logViewDelegate; |
61 | 61 | @property (nonatomic, retain) KMBSLogPopUp *popUp; |
62 | +@property (nonatomic, retain, readwrite) KMLinkHanlder *linkHandler; | |
62 | 63 | |
63 | 64 | @property (readonly) NSWindow *window; |
64 | 65 |
@@ -119,6 +120,7 @@ static void KMClearRangesFromIndex(KMBSLogViewController *obj, NSUInteger index) | ||
119 | 120 | @synthesize histories = _histories; |
120 | 121 | @synthesize logViewDelegate = _logViewDelegate; |
121 | 122 | @synthesize popUp = _popUp; |
123 | +@synthesize linkHandler = _linkHandler; | |
122 | 124 | |
123 | 125 | @synthesize numberOfMessage = _numberOfMessage; |
124 | 126 |
@@ -138,6 +140,8 @@ static void KMClearRangesFromIndex(KMBSLogViewController *obj, NSUInteger index) | ||
138 | 140 | |
139 | 141 | self.histories = [[[KMHistoryStack alloc] init] autorelease]; |
140 | 142 | self.countedSet = [[[NSCountedSet alloc] init] autorelease]; |
143 | + self.linkHandler = [[[KMLinkHanlder alloc] init] autorelease]; | |
144 | + self.linkHandler.logViewController = self; | |
141 | 145 | |
142 | 146 | NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; |
143 | 147 | [nc addObserver:self |
@@ -172,6 +176,7 @@ static void KMClearRangesFromIndex(KMBSLogViewController *obj, NSUInteger index) | ||
172 | 176 | [_messenger release]; |
173 | 177 | [_logViewDelegate release]; |
174 | 178 | [_popUp release]; |
179 | + [_linkHandler release]; | |
175 | 180 | |
176 | 181 | [super dealloc]; |
177 | 182 | } |
@@ -1165,13 +1170,6 @@ static UInt32 attributeMaskForVisibleMessageIndexDetection() | ||
1165 | 1170 | |
1166 | 1171 | @end |
1167 | 1172 | |
1168 | -#import "CMRHostHandler.h" | |
1169 | -#import "SGDownloadLinkCommand.h" | |
1170 | -#import "CMRThreadLinkProcessor.h" | |
1171 | -#import "CMRDocumentFileManager.h" | |
1172 | - | |
1173 | -#define kBeProfileLinkTemplateKey @"System - be2ch Profile URL" | |
1174 | - | |
1175 | 1173 | #import <SGAppKit/BSHistoryOverlayController.h> |
1176 | 1174 | // 10.6 SDK でビルド警告が出ないようにするために |
1177 | 1175 | enum { |
@@ -1229,292 +1227,6 @@ typedef NSUInteger NSEventSwipeTrackingOptions; | ||
1229 | 1227 | }]; |
1230 | 1228 | } |
1231 | 1229 | |
1232 | -- (void)openMessagesWithIndexes:(NSIndexSet *)indexes | |
1233 | -{ | |
1234 | - if (!indexes || [indexes count] == 0) { | |
1235 | - return; | |
1236 | - } | |
1237 | - | |
1238 | - NSURL *boardURL = self.doc.boardURL; | |
1239 | - CMRHostHandler *handler = [CMRHostHandler hostHandlerForURL:self.doc.boardURL]; | |
1240 | - NSURL *url = [handler readURLWithBoard:boardURL datName:self.doc.datIdentifier start:[indexes firstIndex]+1 end:[indexes lastIndex]+1 nofirst:YES]; | |
1241 | - | |
1242 | - if (url) { | |
1243 | - [[NSWorkspace sharedWorkspace] openURL:url inBackground:[CMRPref openInBg]]; | |
1244 | - } | |
1245 | -} | |
1246 | - | |
1247 | -#pragma mark Previewing (or Downloading) Link | |
1248 | -static inline NSString *urlPathExtension(NSURL *url) | |
1249 | -{ | |
1250 | - CFStringRef extensionRef = CFURLCopyPathExtension((CFURLRef)url); | |
1251 | - if (!extensionRef) { | |
1252 | - return nil; | |
1253 | - } | |
1254 | - NSString *extension = [(NSString *)extensionRef lowercaseString]; | |
1255 | - CFRelease(extensionRef); | |
1256 | - return extension; | |
1257 | -} | |
1258 | - | |
1259 | -- (NSDictionary *)refererThreadInfoForLinkDownloader | |
1260 | -{ | |
1261 | - return [NSDictionary dictionaryWithObjectsAndKeys:self.doc.threadTitle, kRefererTitleKey, [self.doc.threadURL absoluteString], kRefererURLKey, NULL]; | |
1262 | -} | |
1263 | - | |
1264 | -- (BOOL)previewOrDownloadURL:(NSURL *)url | |
1265 | -{ | |
1266 | - if (!url || [[url scheme] isEqualToString:@"mailto"]) { | |
1267 | - return NO; | |
1268 | - } | |
1269 | - | |
1270 | - NSArray *extensions = [CMRPref linkDownloaderExtensionTypes]; | |
1271 | - NSString *linkExtension = urlPathExtension(url); | |
1272 | - | |
1273 | - if (linkExtension && [extensions containsObject:linkExtension]) { | |
1274 | - SGDownloadLinkCommand *dlCmd = [SGDownloadLinkCommand functorWithObject:[url absoluteString]]; | |
1275 | - [dlCmd setRefererThreadInfo:[self refererThreadInfoForLinkDownloader]]; | |
1276 | - [dlCmd execute:self]; | |
1277 | - return YES; | |
1278 | - } | |
1279 | - | |
1280 | - | |
1281 | - id<BSLinkPreviewing> previewer = [CMRPref sharedLinkPreviewer]; | |
1282 | - if (previewer) { | |
1283 | - return [previewer validateLink:url] ? [previewer previewLink:url] : NO; | |
1284 | - } else { | |
1285 | - id<BSImagePreviewerProtocol> oldPreviewer = [CMRPref sharedImagePreviewer]; | |
1286 | - if (oldPreviewer) { | |
1287 | - return [oldPreviewer validateLink:url] ? [oldPreviewer showImageWithURL:url] : NO; | |
1288 | - } | |
1289 | - } | |
1290 | - return NO; | |
1291 | -} | |
1292 | - | |
1293 | -- (void)openURLsWithAppStore:(NSArray *)array | |
1294 | -{ | |
1295 | - [[NSWorkspace sharedWorkspace] openURLs:array | |
1296 | - withAppBundleIdentifier:@"com.apple.appstore" | |
1297 | - options:NSWorkspaceLaunchDefault | |
1298 | - additionalEventParamDescriptor:nil | |
1299 | - launchIdentifiers:NULL]; | |
1300 | -} | |
1301 | - | |
1302 | -- (BOOL)handleExternalLink:(id)aLink forView:(NSView *)aView | |
1303 | -{ | |
1304 | - BOOL shouldPreviewWithNoModifierKey = [CMRPref previewLinkWithNoModifierKey]; | |
1305 | - BOOL isOptionKeyPressed; | |
1306 | - BOOL isFileURL; | |
1307 | - NSURL *url = [NSURL URLWithLink:aLink]; | |
1308 | - NSEvent *theEvent; | |
1309 | - | |
1310 | - theEvent = [[aView window] currentEvent]; | |
1311 | - UTILAssertNotNil(theEvent); | |
1312 | - | |
1313 | - isOptionKeyPressed = (([theEvent modifierFlags] & NSAlternateKeyMask) == NSAlternateKeyMask); | |
1314 | - isFileURL = [url isFileURL]; | |
1315 | - | |
1316 | - if ([CMRPref convertsHttpToItmsIfNeeded] && [[url host] isEqualToString:@"itunes.apple.com"]) { | |
1317 | - NSMutableString *tmp = [[url absoluteString] mutableCopy]; | |
1318 | - if ([tmp hasSuffix:@"?mt=12"]) { // Mac App Store URL ? | |
1319 | - [tmp replaceCharactersInRange:NSMakeRange(0,4) withString:@"macappstore"]; | |
1320 | - NSURL *newURL2 = [NSURL URLWithString:tmp]; | |
1321 | - [tmp release]; | |
1322 | - | |
1323 | - // App Store.app が既に起動しているかどうか? | |
1324 | - NSArray *apps = [[NSWorkspace sharedWorkspace] launchedApplications]; | |
1325 | - id hoge = [apps valueForKey:@"NSApplicationBundleIdentifier"]; | |
1326 | - if ([hoge containsObject:@"com.apple.appstore"]) { | |
1327 | - // 既に起動しているなら直ちに開かせる | |
1328 | - [self openURLsWithAppStore:[NSArray arrayWithObject:newURL2]]; | |
1329 | - return YES; | |
1330 | - } else { | |
1331 | - // App Store.app の起動を試みる | |
1332 | - BOOL launched = [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:@"com.apple.appstore" | |
1333 | - options:NSWorkspaceLaunchWithoutActivation | |
1334 | - additionalEventParamDescriptor:nil | |
1335 | - launchIdentifier:NULL]; | |
1336 | - if (launched) { | |
1337 | - // 起動できたら、遅延実行で当該アプリのページを開かせる(遅延させないとうまくいかない) | |
1338 | - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; | |
1339 | - [alert setAlertStyle:NSInformationalAlertStyle]; | |
1340 | - [alert setMessageText:[self localizedString:@"App Store Waiting Msg"]]; | |
1341 | - [alert setInformativeText:[self localizedString:@"App Store Waiting Info"]]; | |
1342 | - [alert addButtonWithTitle:[self localizedString:@"App Store Continue"]]; | |
1343 | - [alert addButtonWithTitle:[self localizedString:@"App Store Cancel"]]; | |
1344 | - if ([alert runModal] == NSAlertFirstButtonReturn) { | |
1345 | - [self openURLsWithAppStore:[NSArray arrayWithObject:newURL2]]; | |
1346 | - } | |
1347 | - return YES; | |
1348 | - } else { | |
1349 | - // App Store.app が存在しない環境か、他の何らかの理由で起動に失敗。URL を通常通り Web ブラウザで開かせる。 | |
1350 | - return [[NSWorkspace sharedWorkspace] openURL:url inBackground:[CMRPref openInBg]]; | |
1351 | - } | |
1352 | - } | |
1353 | - } else { | |
1354 | - [tmp replaceCharactersInRange:NSMakeRange(0,4) withString:@"itms"]; | |
1355 | - NSURL *newURL = [NSURL URLWithString:tmp]; | |
1356 | - [tmp release]; | |
1357 | - [[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:newURL] | |
1358 | - withAppBundleIdentifier:@"com.apple.iTunes" | |
1359 | - options:NSWorkspaceLaunchDefault | |
1360 | - additionalEventParamDescriptor:nil launchIdentifiers:NULL]; | |
1361 | - return YES; | |
1362 | - } | |
1363 | - } | |
1364 | - | |
1365 | - if (shouldPreviewWithNoModifierKey) { | |
1366 | - if (!isOptionKeyPressed && !isFileURL) { | |
1367 | - if ([self previewOrDownloadURL:url]) return YES; | |
1368 | - } | |
1369 | - } else { | |
1370 | - if (isOptionKeyPressed && !isFileURL) { | |
1371 | - if ([self previewOrDownloadURL:url]) return YES; | |
1372 | - } | |
1373 | - } | |
1374 | - return [[NSWorkspace sharedWorkspace] openURL:url inBackground:[CMRPref openInBg]]; | |
1375 | -} | |
1376 | - | |
1377 | -- (NSIndexSet *)isStandardMessageLink:(id)aLink | |
1378 | -{ | |
1379 | - NSURL *link_; | |
1380 | - CMRHostHandler *handler_; | |
1381 | - NSString *bbs_; | |
1382 | - NSString *key_; | |
1383 | - | |
1384 | - NSUInteger stIndex_; | |
1385 | - NSUInteger endIndex_; | |
1386 | - NSRange moveRange_; | |
1387 | - | |
1388 | - link_ = [NSURL URLWithLink:aLink]; | |
1389 | - handler_ = [CMRHostHandler hostHandlerForURL:link_]; | |
1390 | - if (!handler_) return nil; | |
1391 | - | |
1392 | - if (![handler_ parseParametersWithReadURL:link_ | |
1393 | - bbs:&bbs_ | |
1394 | - key:&key_ | |
1395 | - start:&stIndex_ | |
1396 | - to:&endIndex_ | |
1397 | - showFirst:NULL]) { | |
1398 | - return nil; | |
1399 | - } | |
1400 | - | |
1401 | - if (NSNotFound != stIndex_) { | |
1402 | - moveRange_.location = stIndex_ -1; | |
1403 | - moveRange_.length = (endIndex_ - stIndex_) +1; | |
1404 | - } else { | |
1405 | - return nil; | |
1406 | - } | |
1407 | - | |
1408 | - // 同じ掲示板の同じスレッドならメッセージ移動処理 | |
1409 | - if ([self.doc.bbsIdentifier isEqualToString:bbs_] && [self.doc.datIdentifier isEqualToString:key_]) { | |
1410 | - return [NSIndexSet indexSetWithIndexesInRange:moveRange_]; | |
1411 | - } | |
1412 | - | |
1413 | - return nil; | |
1414 | -} | |
1415 | - | |
1416 | -- (BOOL)isMessageLink:(id)aLink messageIndexes:(NSIndexSet **)indexesPtr | |
1417 | -{ | |
1418 | - NSIndexSet *indexes; | |
1419 | - if (!aLink) return NO; | |
1420 | - | |
1421 | - if ([CMRThreadLinkProcessor isMessageLinkUsingLocalScheme:aLink messageIndexes:indexesPtr]) { | |
1422 | - return YES; | |
1423 | - } else if ((indexes = [self isStandardMessageLink:aLink])) { | |
1424 | - if (indexesPtr != NULL) *indexesPtr = indexes; | |
1425 | - return YES; | |
1426 | - } | |
1427 | - | |
1428 | - return NO; | |
1429 | -} | |
1430 | - | |
1431 | -- (BOOL)clickedOnLink:(id)aLink | |
1432 | -{ | |
1433 | - NSString *boardName_; | |
1434 | - NSURL *boardURL_; | |
1435 | - NSString *filepath_; | |
1436 | - NSString *host_; | |
1437 | - NSString *beParam_; | |
1438 | - NSIndexSet *indexes; | |
1439 | - | |
1440 | - // 同じスレッドのレスへのアンカー | |
1441 | - if ([self isMessageLink:aLink messageIndexes:&indexes]) { | |
1442 | - NSInteger action = [CMRPref threadViewerLinkType]; | |
1443 | - if ([indexes firstIndex] != NSNotFound) { | |
1444 | - switch (action) { | |
1445 | - case ThreadViewerMoveToIndexLinkType: | |
1446 | - [self scrollMessageAtIndex:[indexes firstIndex]]; | |
1447 | - break; | |
1448 | - case ThreadViewerOpenBrowserLinkType: | |
1449 | - [self openMessagesWithIndexes:indexes]; | |
1450 | - break; | |
1451 | - case ThreadViewerResPopUpLinkType: | |
1452 | - break; | |
1453 | - default: | |
1454 | - break; | |
1455 | - } | |
1456 | - } | |
1457 | - | |
1458 | - return YES; | |
1459 | - } | |
1460 | - | |
1461 | - // be Profile | |
1462 | - if ([CMRThreadLinkProcessor isBeProfileLinkUsingLocalScheme:aLink linkParam:&beParam_]) { | |
1463 | - NSString *template_ = SGTemplateResource(kBeProfileLinkTemplateKey); | |
1464 | - NSString *thURL_ = [self.doc.threadURL absoluteString]; | |
1465 | - // #warning 64BIT: Check formatting arguments | |
1466 | - // 2010-03-28 tsawada2 検証済 | |
1467 | - NSString *tmpURL_ = [NSString stringWithFormat:template_, beParam_, thURL_]; | |
1468 | - | |
1469 | - NSURL *accessURL_ = [NSURL URLWithString:tmpURL_]; | |
1470 | - | |
1471 | - return [[NSWorkspace sharedWorkspace] openURL:accessURL_ inBackground:[CMRPref openInBg]]; | |
1472 | - } | |
1473 | - | |
1474 | - // 2ch thread | |
1475 | - if ([CMRThreadLinkProcessor parseThreadLink:aLink boardName:&boardName_ boardURL:&boardURL_ filepath:&filepath_ parsedHost:&host_]) { | |
1476 | - CMRDocumentFileManager *dm; | |
1477 | - NSDictionary *contentInfo_; | |
1478 | - NSString *datIdentifier_; | |
1479 | - | |
1480 | - dm = [CMRDocumentFileManager defaultManager]; | |
1481 | - datIdentifier_ = [dm datIdentifierWithLogPath:filepath_]; | |
1482 | - contentInfo_ = [NSDictionary dictionaryWithObjectsAndKeys: | |
1483 | - [boardURL_ absoluteString], BoardPlistURLKey, | |
1484 | - boardName_, ThreadPlistBoardNameKey, | |
1485 | - datIdentifier_, ThreadPlistIdentifierKey, | |
1486 | - host_, @"candidateHost", | |
1487 | - nil]; | |
1488 | - | |
1489 | - [dm ensureDirectoryExistsWithBoardName:boardName_]; | |
1490 | - // return [[CMRDocumentController sharedDocumentController] showDocumentWithContentOfFile:[NSURL fileURLWithPath:filepath_] boardInfo:contentInfo_]; | |
1491 | - NSError *error = nil; | |
1492 | - KMDocument *document = [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:filepath_] | |
1493 | - display:NO | |
1494 | - error:&error]; | |
1495 | - if(!document) { | |
1496 | - NSLog(@"2ch Link open Error.\n%@", error); | |
1497 | - return NO; | |
1498 | - } | |
1499 | -#warning THIS IS TEST IMPLEMENTATION | |
1500 | - NSLog(@"######## THIS IS TEST IMPLEMENTATION. #######"); | |
1501 | - [document addWindowController:self.view.window.windowController]; | |
1502 | - [document showWindows]; | |
1503 | - | |
1504 | - return YES; | |
1505 | - } | |
1506 | - | |
1507 | - // 2ch (or other) BBS | |
1508 | - if ([CMRThreadLinkProcessor parseBoardLink:aLink boardName:&boardName_ boardURL:&boardURL_]) { | |
1509 | - [[NSApp delegate] showThreadsListForBoard:boardName_ selectThread:nil addToListIfNeeded:YES]; | |
1510 | - return YES; | |
1511 | - } | |
1512 | - | |
1513 | - // 外部リンクと判断 | |
1514 | - return [self handleExternalLink:aLink forView:self.documentView]; | |
1515 | -} | |
1516 | - | |
1517 | - | |
1518 | 1230 | - (void)replyTo:(NSIndexSet *)messageIndexes |
1519 | 1231 | { |
1520 | 1232 | [self.messenger clearQuotation]; |
@@ -33,7 +33,7 @@ | ||
33 | 33 | @end |
34 | 34 | |
35 | 35 | @protocol KMBSLogViewDelegateOwner <NSObject> |
36 | -- (BOOL)clickedOnLink:(id)aLink; | |
36 | +- (KMLinkHanlder *)linkHandler; | |
37 | 37 | |
38 | 38 | - (void)replyTo:(NSIndexSet *)messageIndexes; |
39 | 39 |
@@ -43,7 +43,7 @@ | ||
43 | 43 | #pragma mark NSTextView Delegate |
44 | 44 | - (BOOL)textView:(NSTextView *)textView clickedOnLink:(id)aLink atIndex:(NSUInteger)charIndex |
45 | 45 | { |
46 | - return [self.owner clickedOnLink:aLink]; | |
46 | + return [self.owner.linkHandler clickedOnLink:aLink]; | |
47 | 47 | } |
48 | 48 | |
49 | 49 | #pragma mark CMRThreadView delegate |