Subversion Repositories TruePreview

[/] [trunk/] [Source/] [TruePreview.m] - Blame information for rev 31

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1 jhriggs
/*
2
 * Copyright (c) 2009, Jim Riggs, Christian Serving, L.L.C.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are
7
 * met:
8
 *     * Redistributions of source code must retain the above copyright
9
 *       notice, this list of conditions and the following disclaimer.
10
 *     * Redistributions in binary form must reproduce the above
11
 *       copyright notice, this list of conditions and the following
12
 *       disclaimer in the documentation and/or other materials provided
13
 *       with the distribution.
14
 *     * Neither the name of Christian Serving, L.L.C. nor the names of
15
 *       its contributors may be used to endorse or promote products
16
 *       derived from this software without specific prior written
17
 *       permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 */
31
 
32
#import "TruePreview.h"
33
 
34
@implementation TruePreview
35
 
36
#pragma mark Class initialization
37
 
38
+ (void)initialize {
39 17 jhriggs
  if (self == [TruePreview class]) {
40
    class_setSuperclass(self, NSClassFromString(@"MVMailBundle"));
41
  }
42
 
43
  [super registerBundle];
44 1 jhriggs
 
45 17 jhriggs
  // register the preferences value transformers
46
  [NSValueTransformer
47
    setValueTransformer:[[TruePreviewPreferenceValueTransformer alloc] init]
48
    forName:@"TruePreviewPreferenceValueTransformer"
49
  ];
50
  [NSValueTransformer
51
    setValueTransformer:[[TruePreviewPreferenceValueTransformerDelay alloc] init]
52
    forName:@"TruePreviewPreferenceValueTransformerDelay"
53
  ];
54
  [NSValueTransformer
55
    setValueTransformer:[[TruePreviewPreferenceValueTransformerDelayEditIndicator alloc] init]
56
    forName:@"TruePreviewPreferenceValueTransformerDelayEditIndicator"
57
  ];
58
 
59
  // add our "categories"
60
  [TruePreviewLibraryMessage truePreviewAddAsCategoryToClass:NSClassFromString(@"LibraryMessage")];
61
  [TruePreviewMessageViewer truePreviewAddAsCategoryToClass:NSClassFromString(@"MessageViewer")];
62
  [TruePreviewPreferences truePreviewAddAsCategoryToClass:NSClassFromString(@"NSPreferences")];
63
 
64 1 jhriggs
  // do our swizzles
65 17 jhriggs
  [NSClassFromString(@"LibraryMessage")
66 1 jhriggs
    truePreviewSwizzleMethod:@selector(markAsViewed)
67
    withMethod:@selector(truePreviewMarkAsViewed)
68
    isClassMethod:NO
69
  ];
70 17 jhriggs
  [NSClassFromString(@"MessageViewer")
71
    truePreviewSwizzleMethod:@selector(dealloc)
72
    withMethod:@selector(truePreviewDealloc)
73 1 jhriggs
    isClassMethod:NO
74
  ];
75 17 jhriggs
  [NSClassFromString(@"MessageViewer")
76 23 jhriggs
    truePreviewSwizzleMethod:@selector(forwardAsAttachment:)
77
    withMethod:@selector(truePreviewForwardAsAttachment:)
78
    isClassMethod:NO
79
  ];
80
  [NSClassFromString(@"MessageViewer")
81
    truePreviewSwizzleMethod:@selector(forwardMessage:)
82
    withMethod:@selector(truePreviewForwardMessage:)
83
    isClassMethod:NO
84
  ];
85
  [NSClassFromString(@"MessageViewer")
86 17 jhriggs
    truePreviewSwizzleMethod:@selector(markAsRead:)
87
    withMethod:@selector(truePreviewMarkAsRead:)
88
    isClassMethod:NO
89
  ];
90
  [NSClassFromString(@"MessageViewer")
91
    truePreviewSwizzleMethod:@selector(markAsUnread:)
92
    withMethod:@selector(truePreviewMarkAsUnread:)
93
    isClassMethod:NO
94
  ];
95
  [NSClassFromString(@"MessageViewer")
96 23 jhriggs
    truePreviewSwizzleMethod:@selector(messageNoLongerDisplayedInTextView:)
97
    withMethod:@selector(truePreviewMessageNoLongerDisplayedInTextView:)
98
    isClassMethod:NO
99
  ];
100
  [NSClassFromString(@"MessageViewer")
101 17 jhriggs
    truePreviewSwizzleMethod:@selector(messageWasDisplayedInTextView:)
102
    withMethod:@selector(truePreviewMessageWasDisplayedInTextView:)
103
    isClassMethod:NO
104
  ];
105
  [NSClassFromString(@"MessageViewer")
106 23 jhriggs
    truePreviewSwizzleMethod:@selector(replyAllMessage:)
107
    withMethod:@selector(truePreviewReplyAllMessage:)
108 17 jhriggs
    isClassMethod:NO
109
  ];
110 23 jhriggs
  [NSClassFromString(@"MessageViewer")
111
    truePreviewSwizzleMethod:@selector(replyMessage:)
112
    withMethod:@selector(truePreviewReplyMessage:)
113
    isClassMethod:NO
114
  ];
115 17 jhriggs
  [NSClassFromString(@"NSPreferences")
116
   truePreviewSwizzleMethod:@selector(sharedPreferences)
117
   withMethod:@selector(truePreviewSharedPreferences)
118
   isClassMethod:YES
119
   ];
120 1 jhriggs
 
121 17 jhriggs
  // set defaults
122 1 jhriggs
  [[NSUserDefaults standardUserDefaults]
123 17 jhriggs
    registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
124
      [NSNumber numberWithInt:TRUEPREVIEW_DELAY_IMMEDIATE], @"TruePreviewDelay",
125 23 jhriggs
      [NSNumber numberWithInt:NSOnState], @"TruePreviewReply",
126
      [NSNumber numberWithInt:NSOnState], @"TruePreviewForward",
127 17 jhriggs
      [NSNumber numberWithInt:NSOnState], @"TruePreviewWindow",
128
      [NSNumber numberWithInt:NSOffState], @"TruePreviewScroll",
129
      nil
130 1 jhriggs
    ]
131
  ];
132
 
133 17 jhriggs
  // we're all set
134 1 jhriggs
  NSLog(
135
    @"Loaded TruePreview plugin %@",
136
    [[NSBundle bundleForClass:[TruePreview class]] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]
137
  );
138
}
139
 
140
#pragma mark MVMailBundle class methods
141
 
142
+ (BOOL)hasPreferencesPanel {
143
  return YES;
144
}
145
 
146
+ (NSString*)preferencesOwnerClassName {
147 17 jhriggs
  return @"TruePreviewPreferencesModule";
148 1 jhriggs
}
149
 
150
+ (NSString*)preferencesPanelName {
151
  return @"TruePreview";
152
}
153
 
154
@end
155
 
156
@implementation NSObject (TruePreviewObject)
157
 
158
#pragma mark Class methods
159
 
160 17 jhriggs
+ (void)truePreviewAddAsCategoryToClass:(Class)inClass {
161
  unsigned int theCount = 0;
162
  Method* theMethods = class_copyMethodList(object_getClass([self class]), &theCount);
163
  Class theClass = object_getClass(inClass);
164
  unsigned int i = 0;
165
 
166
  while (YES) {
167
    for (i = 0; i < theCount; i++) {
168
      if (
169
        !class_addMethod(
170
          theClass,
171
          method_getName(theMethods[i]),
172
          method_getImplementation(theMethods[i]),
173
          method_getTypeEncoding(theMethods[i])
174
        )
175
      ) {
176
        NSLog(
177
          @"truePreviewAddAsCategoryToClass: could not add %@ to %@",
178
          NSStringFromSelector(method_getName(theMethods[i])),
179
          inClass
180
        );
181
      }
182
    }
183
 
184
    if (theMethods != nil) {
185
      free(theMethods);
186
    }
187
 
188
    if (theClass != inClass) {
189
      theClass = inClass;
190
      theMethods = class_copyMethodList([self class], &theCount);
191
    }
192
    else {
193
      break;
194
    }
195
  }
196
}
197
 
198 1 jhriggs
+ (void)truePreviewSwizzleMethod:(SEL)inOriginalSelector withMethod:(SEL)inReplacementSelector isClassMethod:(BOOL)inIsClassMethod {
199
  Method theOriginalMethod = (!inIsClassMethod
200
    ? class_getInstanceMethod([self class], inOriginalSelector)
201
    : class_getClassMethod([self class], inOriginalSelector)
202
  );
203
  Method theReplacementMethod = (!inIsClassMethod
204
    ? class_getInstanceMethod([self class], inReplacementSelector)
205
    : class_getClassMethod([self class], inReplacementSelector)
206
  );
207
 
208
  method_exchangeImplementations(theOriginalMethod, theReplacementMethod);
209
}
210
 
211
@end