home *** CD-ROM | disk | FTP | other *** search
-
- #import <appkit/appkit.h>
- #import <misckit/MiscSortedList.h>
- #import <misckit/MiscAppDefaults.h>
- #import "../Preferences.subproj/preferences.h"
-
- #import "decode.h"
-
- #import "NiftyMatrix.h"
- #import "DecodeCell.h"
- #import "NNTP.h"
- #import "MainWindowControl.h"
- #import "ArticleSetMatrix.h"
- #import "ArticleSet.h"
- #import "Article.h"
- #import "MatrixScroller.h"
-
- #import "DecoderController.h"
-
- #import "descriptors.h"
-
- @implementation DecoderController : Object
-
- - (void) doDecoding:sender
- // Sender is the MainWindowControl. This is activated after the user
- // chooses Tools->UUdecode from the menu.
- {
- int articlesSelected;
-
- // Keep the main window control around cause we'll need it.
- mainWindowControl = sender;
-
- articlesSelected = [[mainWindowControl articleSet] numSelCells];
- // If multiple articles are selected then we have to do the
- // modal panel.
-
- setDecodeDepositPathname([NXApp defaultValue:DEFAULT_SAVE_PATH]);
-
- if (articlesSelected > 1) {
- [self showDecodePanel:self];
- }
- else
- // If only a single article is selected then we can grab
- // the text from the text object.
- if (articlesSelected == 1) {
- Text *articleText = [sender articleText];
- NXStream *textStream;
- int status;
-
- textStream = [articleText stream];
- NXSeek(textStream,0,NX_FROMSTART);
-
- uud_start();
- status = uudecode(textStream);
-
- if (status == -1) {
- NXRunAlertPanel("UUdecode Error",
- "Could not decode the selected article.", "OK", NULL, NULL);
- }
- else
- if (status == 0 && uudecode_state() == SKIP_LEADING) {
- NXRunAlertPanel("UUdecode Error",
- "Could not find the end of article.", "OK", NULL, NULL);
- }
- decode_end();
- }
- }
-
- - (void) uudecodeMultipleArticles
- // Begin the uudecoding.
- {
- DecodeCell * selectedArticleCell;
- int selectedArticleCount;
- int i;
-
- [decodeAndAbortButton setEnabled:NO];
- continueDecoding = YES;
- // Start with the first cell that isn't decoded. Usually that's the first
- // one, but if the user clicks the "Abort" button and then decides to
- // continue...
- // currentDecodeIndex = 0;
-
- selectedArticleCount = [selectedArticleMatrix cellCount];
- for (i=0; i<selectedArticleCount; i++) {
- selectedArticleCell = [selectedArticleMatrix cellAt:i :0];
- if ([selectedArticleCell decodeStatus] == NOT_DECODED) {
- break;
- }
- }
- currentDecodeIndex = i;
-
- // This starts the chain of decoding. If there are more articles
- // and the abort button is not clicked then they will get done in turn.
- if (currentDecodeIndex < selectedArticleCount) {
- uud_start();
- [self uudecodeArticle:[[selectedArticleMatrix cellAt:
- currentDecodeIndex :0] articleIndex]];
- }
- }
-
- - (void) uudecodeArticle:(int)articleIndex
- // This method uudecodes the given article (the articleIndex is it's place in
- // the articleMatrix in the main window), then primes (delay performs) the next
- // not yet decoded article if the abort button hasn't been clicked.
- // This is just so you have something like multithreading without actually
- // having to write it.
- {
- // Has the abort button been clicked?
- if (continueDecoding) {
- id nntpServer = [mainWindowControl nntpServer];
- Article * article;
- char * body;
- int selectedArticleCount;
-
- // Get and load the article.
- article = [[mainWindowControl articleMatrix] cellAt:articleIndex :0];
- [nntpServer loadArticleBody:article toString:&body];
-
- if (body) {
- // It's probably not the most efficient thing to put the article
- // in a stream, but that's how the uudecode function now expects
- // it.
- NXStream * articleStream = NXOpenMemory(body, strlen(body),
- NX_READONLY);
- DecodeCell * currentCell;
- int currentStatus;
- int px,py;
-
- currentStatus = uudecode(articleStream);
- NXCloseMemory(articleStream, NX_FREEBUFFER);
-
- // Should it only be setRead if it's successful? For now as you
- // can see it marks it read regardless.
- //[article setRead];
-
- // Set the image in the cell to show success or failure.
- currentCell = [selectedArticleMatrix cellAt:currentDecodeIndex :0];
- [currentCell setDecodeStatus:(currentStatus == 0) ?
- DECODE_SUCCESSFUL : DECODE_FAILED];
- [selectedArticleMatrix getRow:&px andCol:&py ofCell:currentCell];
- [selectedArticleMatrix drawCellAt:px :py];
- [selectedArticleMatrix scrollCellToVisible:px upperOffset:1.5 lowerOffset:1.5];
-
- //stop if error
- if(currentStatus){
- decode_end();
- return;
- }
- }
-
- // Set the next cell for uudecoding if there are any more.
- selectedArticleCount = [selectedArticleMatrix cellCount];
- currentDecodeIndex++;
- if (currentDecodeIndex < selectedArticleCount) {
- DecodeCell * nextCell;
-
- nextCell = [selectedArticleMatrix cellAt:currentDecodeIndex :0];
- // This is probably bad (passing an int to the with argument).
- [self perform:_cmd with:(void*)[nextCell articleIndex]
- afterDelay:0.0 cancelPrevious:NO];
- }
- // We are done decoding so set the button back to say "Decode".
- else {
- //[decodeAndAbortButton setState:0];
- continueDecoding = NO;
- decode_end();
- [panel close];
- [(ArticleSet *)mainWindowControl markRead:self];
- [NXApp abortModal];
- }
- }
- }
-
- - (void) showDecodePanel:sender
- {
- if (panel == nil) {
- [NXApp loadNibSection:"ModalDecodingPanel.nib" owner:self];
- [self setupDecodePanel];
- }
-
- [decodeAndAbortButton setState:0];
- [decodeAndAbortButton setEnabled:YES];
- [self loadMatrixWithArticles];
- [panel orderFront:self];
- [NXApp runModalFor:panel];
- }
-
- - (void) setupDecodePanel
- // This is called only the first time the nib is loaded so we can swap
- // the matrix with a nifty matrix.
- {
- NiftyMatrix * niftyMatrix;
- ScrollView * scrollView = [[selectedArticleMatrix superview] superview];
- NXRect scrollBoundsRect;
- NXSize interCellSpacing;
- NXSize cellSize;
-
- // Determine the Matrix bounds.
- [scrollView getBounds:&scrollBoundsRect];
-
- // Prepare a NiftyMatrix to go inside the ScrollView.
- niftyMatrix = [[NiftyMatrix alloc] initFrame:&scrollBoundsRect
- mode:NX_RADIOMODE cellClass:[DecodeCell class]
- numRows:5 numCols:1];
-
- // Eliminate intercell spacing.
- interCellSpacing.height = 0.0;
- interCellSpacing.width = 0.0;
- [niftyMatrix setIntercell:&interCellSpacing];
-
- // Set the Cell size to the width of the ScrollView's bounds rect.
- [niftyMatrix getCellSize:&cellSize];
- cellSize.width = NX_WIDTH (&scrollBoundsRect);
- [niftyMatrix setCellSize:&cellSize];
- [niftyMatrix sizeToCells];
-
- // Set NiftyMatrix sizing parameters.
- [niftyMatrix setAutosizeCells:YES];
- [[niftyMatrix superview] setAutoresizeSubviews:YES];
- [niftyMatrix setAutosizing:NX_WIDTHSIZABLE];
-
- // Scroll when the user clicks in the EnhancedNiftyMatrix and then
- // drags the mouse out of contentView.
- [niftyMatrix setAutoscroll:YES];
-
- // Stick the matrix in the ScrollView.
- [scrollView setDocView:niftyMatrix];
- [niftyMatrix display];
- [selectedArticleMatrix free];
- selectedArticleMatrix = niftyMatrix;
- }
-
- - (void) loadMatrixWithArticles
- // Loads the nifty matrix with the selected cells from the article matrix.
- // We also sort them so that multipart pics will probably be in the correct
- // order.
- {
- List * articleList = [[mainWindowControl articleMatrix] cellList];
- MiscSortedList * sortedArticleList = [[MiscSortedList alloc] init];
- Article * articleCell;
- DecodeCell * sortedArticleCell;
- int i;
- int sortedArticleCount;
- int oldSortType=[Article sortType];
-
- // Get the selected articles and sort them.
- [sortedArticleList setSortEnabled:NO];
- sortedArticleList = [[mainWindowControl articleMatrix]
- getSelectedCells:sortedArticleList];
- [Article setSortType:SORT_BY_SUBJECT];
- [sortedArticleList sort];
- [Article setSortType:oldSortType];
-
- // Resize our matrix so it will hold the new selected cells.
- sortedArticleCount = [sortedArticleList count];
- [selectedArticleMatrix renewRows:sortedArticleCount cols:1];
-
- // Fill the matrix.
- for (i=0; i<sortedArticleCount; i++) {
- sortedArticleCell = [selectedArticleMatrix cellAt:i :0];
- articleCell = [sortedArticleList objectAt:i];
- // The article index is the index of the article in the articleMatrix.
- [sortedArticleCell setArticleIndex:[articleList indexOf:articleCell]];
- [sortedArticleCell setStringValue:
- [articleCell header]->fieldBody[SUBJECT]];
- // Since we might be reusing cells we should set this explicitly.
- [sortedArticleCell setDecodeStatus:NOT_DECODED];
- }
-
- // Scroll to the top and redisplay.
- // [[selectedArticleMatrix window] disableFlushWindow];
- [selectedArticleMatrix scrollCellToVisible:0 :0];
- [selectedArticleMatrix sizeToCells];
- [selectedArticleMatrix display];
- // [[selectedArticleMatrix window] reenableFlushWindow];
- // [[selectedArticleMatrix window] flushWindow];
-
- // Set our counter to display the number of selected articles.
- [numArticlesTF setIntValue:[selectedArticleMatrix cellCount]];
- }
-
- - decodeOrAbortButtonClicked:sender
- // The sender is the "Decode" or "Abort" button (the same button with
- // a title and alt-title).
- {
- // The "Decode" button was clicked.
- if ([sender state] == 1) {
- [self uudecodeMultipleArticles];
- }
- // The "Abort" button was clicked.
- else {
- continueDecoding = NO;
- }
- return self;
- }
-
- - cancelModalPanel:sender
- // The cancel button was clicked
- {
- continueDecoding = NO;
- decode_end();
- [NXApp stopModal];
- [panel close];
-
- return self;
- }
-
- @end
-
-