Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "common.h"
2
#import "MuDocumentController.h"
3
#import "MuLibraryController.h"
4
5
static void showAlert(NSString *msg, NSString *filename)
6
{
7
UIAlertView *alert = [[UIAlertView alloc]
8
initWithTitle: msg
9
message: filename
10
delegate: nil
11
cancelButtonTitle: @"Okay"
12
otherButtonTitles: nil];
13
[alert show];
14
[alert release];
15
}
16
17
@implementation MuLibraryController
18
{
19
NSArray *files;
20
NSTimer *timer;
21
MuDocRef *doc;
22
NSString *_filename;
23
char *_filePath;
24
}
25
26
- (void) viewWillAppear: (BOOL)animated
27
{
28
[super viewWillAppear:animated];
29
[self setTitle: @"PDF, XPS, CBZ and EPUB Documents"];
30
[self reload];
31
printf("library viewWillAppear (starting reload timer)\n");
32
timer = [NSTimer timerWithTimeInterval: 3
33
target: self selector: @selector(reload) userInfo: nil
34
repeats: YES];
35
[[NSRunLoop currentRunLoop] addTimer: timer forMode: NSDefaultRunLoopMode];
36
}
37
38
- (void) viewWillDisappear: (BOOL)animated
39
{
40
[super viewWillDisappear:animated];
41
printf("library viewWillDisappear (stopping reload timer)\n");
42
[timer invalidate];
43
timer = nil;
44
}
45
46
- (void) reload
47
{
48
if (files) {
49
[files release];
50
files = nil;
51
}
52
53
NSFileManager *fileman = [NSFileManager defaultManager];
54
NSString *docdir = [NSString stringWithFormat: @"%@/Documents", NSHomeDirectory()];
55
NSMutableArray *outfiles = [[NSMutableArray alloc] init];
56
NSDirectoryEnumerator *direnum = [fileman enumeratorAtPath:docdir];
57
NSString *file;
58
BOOL isdir;
59
while (file = [direnum nextObject]) {
60
NSString *filepath = [docdir stringByAppendingPathComponent:file];
61
if ([fileman fileExistsAtPath:filepath isDirectory:&isdir] && !isdir) {
62
[outfiles addObject:file];
63
}
64
}
65
66
files = outfiles;
67
68
[[self tableView] reloadData];
69
}
70
71
- (void) dealloc
72
{
73
[doc release];
74
[files release];
75
[super dealloc];
76
}
77
78
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)o
79
{
80
return YES;
81
}
82
83
- (NSInteger) numberOfSectionsInTableView: (UITableView*)tableView
84
{
85
return 1;
86
}
87
88
- (NSInteger) tableView: (UITableView*)tableView numberOfRowsInSection: (NSInteger)section
89
{
90
return [files count];
91
}
92
93
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
94
{
95
if (buttonIndex == [actionSheet destructiveButtonIndex])
96
{
97
char filename[PATH_MAX];
98
NSInteger row = [actionSheet tag];
99
100
dispatch_sync(queue, ^{});
101
102
strcpy(filename, [NSHomeDirectory() UTF8String]);
103
strcat(filename, "/Documents/");
104
strcat(filename, [[files objectAtIndex: row] UTF8String]);
105
106
printf("delete document '%s'\n", filename);
107
108
unlink(filename);
109
110
[self reload];
111
}
112
}
113
114
- (void) onTapDelete: (UIControl*)sender
115
{
116
NSInteger row = [sender tag];
117
NSString *title = [NSString stringWithFormat: @"Delete %@?", [files objectAtIndex:row]];
118
UIActionSheet *sheet = [[UIActionSheet alloc]
119
initWithTitle: title
120
delegate: self
121
cancelButtonTitle: @"Cancel"
122
destructiveButtonTitle: @"Delete"
123
otherButtonTitles: nil];
124
[sheet setTag: row];
125
[sheet showInView: [self tableView]];
126
[sheet release];
127
}
128
129
- (UITableViewCell*) tableView: (UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath*)indexPath
130
{
131
static NSString *cellid = @"MuCellIdent";
132
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellid];
133
if (!cell)
134
cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: cellid] autorelease];
135
NSInteger row = [indexPath row];
136
[[cell textLabel] setText: [files objectAtIndex: row]];
137
[[cell textLabel] setFont: [UIFont systemFontOfSize: 20]];
138
139
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
140
[deleteButton setImage: [UIImage imageNamed: @"x_alt_blue.png"] forState: UIControlStateNormal];
141
[deleteButton setFrame: CGRectMake(0, 0, 35, 35)];
142
[deleteButton addTarget: self action: @selector(onTapDelete:) forControlEvents: UIControlEventTouchUpInside];
143
[deleteButton setTag: row];
144
[cell setAccessoryView: deleteButton];
145
146
return cell;
147
}
148
149
- (void) tableView: (UITableView*)tableView didSelectRowAtIndexPath: (NSIndexPath*)indexPath
150
{
151
NSInteger row = [indexPath row];
152
[self openDocument: [files objectAtIndex: row]];
153
}
154
155
static NSString *alteredfilename(NSString *name, int i)
156
{
157
if (i == 0)
158
return name;
159
160
NSString *nam = [name stringByDeletingPathExtension];
161
NSString *e = [name pathExtension];
162
return [[[NSString alloc] initWithFormat:@"%@(%d).%@", nam, i, e] autorelease];
163
}
164
165
static NSString *moveOutOfInbox(NSString *docpath)
166
{
167
if ([docpath hasPrefix:@"Inbox/"])
168
{
169
NSFileManager *fileMan = [NSFileManager defaultManager];
170
NSString *base = [docpath stringByReplacingOccurrencesOfString:@"Inbox/" withString:@""];
171
172
for (int i = 0; YES; i++)
173
{
174
NSString *newname = alteredfilename(base, i);
175
NSString *newfullpath = [NSString pathWithComponents:[NSArray arrayWithObjects:NSHomeDirectory(), @"Documents", newname, nil]];
176
177
if (![fileMan fileExistsAtPath:newfullpath])
178
{
179
NSString *fullpath = [NSString pathWithComponents:[NSArray arrayWithObjects:NSHomeDirectory(), @"Documents", docpath, nil]];
180
[fileMan copyItemAtPath:fullpath toPath:newfullpath error:nil];
181
[fileMan removeItemAtPath:fullpath error:nil];
182
return newname;
183
}
184
}
185
}
186
187
return docpath;
188
}
189
190
- (void) openDocument: (NSString*)nsfilename
191
{
192
nsfilename = moveOutOfInbox(nsfilename);
193
NSString *nspath = [[NSArray arrayWithObjects:NSHomeDirectory(), @"Documents", nsfilename, nil]
194
componentsJoinedByString:@"/"];
195
_filePath = malloc(strlen([nspath UTF8String])+1);
196
if (_filePath == NULL) {
197
showAlert(@"Out of memory in openDocument", nsfilename);
198
return;
199
}
200
201
strcpy(_filePath, [nspath UTF8String]);
202
203
dispatch_sync(queue, ^{});
204
205
printf("open document '%s'\n", _filePath);
206
207
_filename = [nsfilename retain];
208
[doc release];
209
doc = [[MuDocRef alloc] initWithFilename:_filePath];
210
if (!doc) {
211
showAlert(@"Cannot open document", nsfilename);
212
return;
213
}
214
215
if (fz_needs_password(ctx, doc->doc))
216
[self askForPassword: @"'%@' needs a password:"];
217
else
218
[self onPasswordOkay];
219
}
220
221
- (void) askForPassword: (NSString*)prompt
222
{
223
UIAlertView *passwordAlertView = [[UIAlertView alloc]
224
initWithTitle: @"Password Protected"
225
message: [NSString stringWithFormat: prompt, [_filename lastPathComponent]]
226
delegate: self
227
cancelButtonTitle: @"Cancel"
228
otherButtonTitles: @"Done", nil];
229
[passwordAlertView setAlertViewStyle: UIAlertViewStyleSecureTextInput];
230
[passwordAlertView show];
231
[passwordAlertView release];
232
}
233
234
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
235
{
236
char *password = (char*) [[[alertView textFieldAtIndex: 0] text] UTF8String];
237
[alertView dismissWithClickedButtonIndex: buttonIndex animated: TRUE];
238
if (buttonIndex == 1) {
239
if (fz_authenticate_password(ctx, doc->doc, password))
240
[self onPasswordOkay];
241
else
242
[self askForPassword: @"Wrong password for '%@'. Try again:"];
243
} else {
244
[self onPasswordCancel];
245
}
246
}
247
248
- (void) onPasswordOkay
249
{
250
MuDocumentController *document = [[MuDocumentController alloc] initWithFilename: _filename path:_filePath document: doc];
251
if (document) {
252
[self setTitle: @"Library"];
253
[[self navigationController] pushViewController: document animated: YES];
254
[document release];
255
}
256
[_filename release];
257
free(_filePath);
258
}
259
260
- (void) onPasswordCancel
261
{
262
[_filename release];
263
free(_filePath);
264
printf("close document (password cancel)\n");
265
}
266
267
@end
268
269