/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ /* AbiSource Application Framework * Copyright (C) 2005 Francis James Franklin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #import #import "AbiMailMan_Controller.h" #import "AbiMailMan_DataSetController.h" #import "AbiMailMan_DocumentChooser.h" #import "AbiMailMan_Toolbar.h" @implementation AbiMailMan_DataSetFieldSource - (id)init { if (self = [super init]) { m_FieldList = 0; m_Document = 0; } return self; } - (void)dealloc { if (m_FieldList) { [m_FieldList release]; m_FieldList = 0; } if (m_Document) { [m_Document release]; m_Document = 0; } [super dealloc]; } - (void)windowDidLoad { [oNewField setEnabled:YES]; [oInsertField setEnabled:NO]; } - (void)setFieldList:(NSArray *)fieldList { [oFieldTable deselectAll:self]; [oInsertField setEnabled:NO]; if (m_FieldList) { [m_FieldList release]; m_FieldList = 0; } if (fieldList) { m_FieldList = fieldList; [m_FieldList retain]; } [oFieldTable reloadData]; } - (void)setDocument:(id )document { [oFieldTable deselectAll:self]; [oInsertField setEnabled:NO]; if (m_Document) { [m_Document release]; m_Document = 0; } if (document) { m_Document = document; [m_Document retain]; } } - (IBAction)aFieldTable:(id)sender { // [oDataSetController logError:@"Not implemented!" forMethod:@"aFieldTable:"]; // TODO - or not... don't really need this action } - (IBAction)aNewField:(id)sender { [oDataSetController logError:@"Not implemented!" forMethod:@"aNewField:"]; // TODO } - (IBAction)aInsertField:(id)sender { [oDataSetController logEntry:@"-" forMethod:@"aInsertField:"]; if ([oDataSetController confirmDocument] && m_FieldList) { int row = [oFieldTable selectedRow]; if ((row >= 0) && (row < (int) [m_FieldList count])) { NSString * field_name = (NSString *) [m_FieldList objectAtIndex:row]; [oDataSetController logEntry:[NSString stringWithFormat:@"field=\"%@\"", field_name] forMethod:@"aInsertField:"]; [m_Document unsetDocumentMailMergeFields]; [m_Document insertDocumentMailMergeField:field_name]; } } } /* NSTableView delegate method */ - (void)tableViewSelectionDidChange:(NSNotification *)aNotification { int selection_count = [oFieldTable numberOfSelectedRows]; if (selection_count) { [oInsertField setEnabled:YES]; } else { [oInsertField setEnabled:NO]; } } /* NSTableDataSource methods */ - (int)numberOfRowsInTableView:(NSTableView *)aTableView { int number = 0; if (m_FieldList) { number = (int) [m_FieldList count]; } return number; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { NSString * field_name = @""; if (m_FieldList) if (((unsigned) rowIndex) < [m_FieldList count]) field_name = (NSString *) [m_FieldList objectAtIndex:((unsigned) rowIndex)]; return field_name; } @end @implementation AbiMailMan_DataSetController - (id)initWithAbiWord:(XAP_CocoaPlugin *)AbiWord withController:(AbiMailMan_Controller *)controller withDataSet:(NSMutableArray *)dataset { if (self = [super initWithWindowNibName:@"DataSetManager"]) { m_AbiWord = AbiWord; m_Document = 0; m_Controller = controller; m_Toolbar = 0; m_DataSet = 0; m_MailMergeSource = 0; if (dataset) { m_DataSet = dataset; [m_DataSet retain]; } m_DataSetUntitled = NO; m_DataSetEdited = NO; } return self; } - (void)dealloc { if (m_DataSet) { [m_DataSet release]; m_DataSet = 0; } if (m_Document) { [m_Document release]; m_Document = 0; } if (m_MailMergeSource) { [m_MailMergeSource release]; m_MailMergeSource = 0; } if (m_Toolbar) { [m_Toolbar release]; m_Toolbar = 0; } [super dealloc]; } - (void)windowDidLoad { m_Toolbar = [[AbiMailMan_Toolbar alloc] initWithController:m_Controller withDataSet:self]; unsigned desired_count = 0; if (m_DataSet) { NSMutableArray * headers = (NSMutableArray *) [m_DataSet objectAtIndex:0]; desired_count = [headers count]; } desired_count += 8; NSArray * columns = [oDataSetTable tableColumns]; unsigned count = [columns count]; unsigned i; for (i = 0; i < count; i++) { NSTableColumn * column = (NSTableColumn *) [columns objectAtIndex:i]; [column setIdentifier:[NSNumber numberWithUnsignedInt:i]]; [column setMinWidth:40.0f]; [column setMaxWidth:1000.0f]; [column setWidth:80.0f]; [column setResizable:YES]; [column setEditable:YES]; } while (count < desired_count) { NSTableColumn * column = [[NSTableColumn alloc] initWithIdentifier:[NSNumber numberWithUnsignedInt:count]]; [oDataSetTable addTableColumn:column]; [column setMinWidth:40.0f]; [column setMaxWidth:1000.0f]; [column setWidth:80.0f]; [column setResizable:YES]; [column setEditable:YES]; [column release]; ++count; } if (m_DataSet) { columns = [oDataSetTable tableColumns]; NSMutableArray * headers = (NSMutableArray *) [m_DataSet objectAtIndex:0]; unsigned headers_count = [headers count]; unsigned i; for (i = 0; i < headers_count; i++) { NSString * field_name = (NSString *) [headers objectAtIndex:i]; NSTableColumn * column = (NSTableColumn *) [columns objectAtIndex:i]; [[column headerCell] setStringValue:field_name]; } } [oDataSetTable setDelegate:self]; [oDataSetTable setDataSource:self]; [oDataSetFieldSource windowDidLoad]; if (m_DataSet) { NSMutableArray * headers = (NSMutableArray *) [m_DataSet objectAtIndex:0]; [oDataSetFieldSource setFieldList:headers]; } } - (void)setDocument:(id )document { [self logEntry:@"-" forMethod:@"setDocument:"]; if (m_Document) { [m_Document release]; m_Document = 0; } if (document) { m_Document = document; [m_Document retain]; [self logEntry:[NSString stringWithFormat:@"document title: \"%@\"", [m_Document title]] forMethod:@"setDocument:"]; [oDocumentName setStringValue:[NSString stringWithFormat:@"Associated AbiWord Document: %@", [m_Document title]]]; } else { [oDocumentName setStringValue:@"Associated AbiWord Document: (none)"]; } [oDataSetFieldSource setDocument:m_Document]; } - (void)setMailMergeSource:(NSString *)path { [self logEntry:[NSString stringWithFormat:@"path=\"%@\"", path] forMethod:@"setMailMergeSource:"]; if (m_MailMergeSource) { [m_MailMergeSource release]; m_MailMergeSource = 0; } if (path) { m_MailMergeSource = path; [m_MailMergeSource retain]; NSWindow * window = [self window]; [window setRepresentedFilename:path]; [window setTitle:[path lastPathComponent]]; m_DataSetUntitled = NO; } } - (void)setUntitledWithNumber:(unsigned)number { if (m_MailMergeSource) { [self logError:@"Attempt to retitle titled data set as untitled!" forMethod:@"setUntitledWithNumber:"]; } else if (m_DataSetUntitled) { [self logError:@"Attempt to retitle untitled data set as untitled!" forMethod:@"setUntitledWithNumber:"]; } else { [self logEntry:[NSString stringWithFormat:@"number=\"%d\"", number] forMethod:@"setUntitledWithNumber:"]; [[self window] setTitle:[NSString stringWithFormat:@"AbiMailMan Untitled %u", number]]; m_DataSetUntitled = YES; } } - (IBAction)aDataSetTable:(id)sender { // [self logError:@"Not implemented!" forMethod:@"aDataSetTable:"]; // TODO - or not... don't really need this action } - (IBAction)aSelectDocument:(id)sender { NSArray * documents = [m_AbiWord documents]; unsigned document_count = [documents count]; if (document_count == 0) { [self logEntry:@"No AbiWord documents open..." forMethod:@"aSelectDocument:"]; [self setDocument:nil]; } else { [self logEntry:@"-" forMethod:@"aSelectDocument:"]; NSMutableArray * titles = [NSMutableArray arrayWithCapacity:document_count]; unsigned i; for (i = 0; i < document_count; i++) { id document = (id ) [documents objectAtIndex:i]; [titles addObject:[document title]]; } AbiMailMan_DocumentChooser * dialog = [[AbiMailMan_DocumentChooser alloc] initWithDocumentList:titles]; [NSApp runModalForWindow:[dialog window]]; int selection = [dialog indexOfSelectedItem]; [dialog close]; [dialog release]; if (selection >= 0) { id document = (id ) [documents objectAtIndex:selection]; [self setDocument:document]; } } } - (void)saveDataSet:(id)sender { [self logError:@"Not implemented!" forMethod:@"saveDataSet:"]; // TODO } - (void)updateDocumentFields:(id)sender { [self logEntry:@"-" forMethod:@"updateDocumentFields:"]; if ([self confirmDocument]) { int selection_count = [oDataSetTable numberOfSelectedRows]; if (selection_count == 1) { unsigned selected_row = [oDataSetTable selectedRow] + 1; unsigned max_rowcount = [m_DataSet count]; if ((selected_row > 0) && (selected_row < max_rowcount)) // should be true always { NSArray * fields = (NSArray *) [m_DataSet objectAtIndex:0]; NSArray * values = (NSArray *) [m_DataSet objectAtIndex:selected_row]; [m_Document setDocumentMailMergeFields:fields]; [m_Document setDocumentMailMergeValues:[NSDictionary dictionaryWithObjects:values forKeys:fields]]; } } else if (selection_count == 0) { [m_Document unsetDocumentMailMergeFields]; } // else do nothing... TODO: arrange to disable Update Document toolbar button for multiple selection } } - (void)printDocument:(id)sender { [self logError:@"Not implemented!" forMethod:@"printDocument:"]; // TODO } - (BOOL)confirmDocument { BOOL bConfirmed = NO; if (m_Document) if ([m_Document documentStillExists]) if (YES /* TODO: check that the document is still associated with this file... */) { /* The document may have a different title (if it has been saved), so update this: */ [oDocumentName setStringValue:[NSString stringWithFormat:@"Associated AbiWord Document: %@", [m_Document title]]]; bConfirmed = YES; } if (!bConfirmed) { [self setDocument:nil]; // TODO: this data set is no longer associated with a document... // TODO: set toolbar item states, etc. } return bConfirmed; } - (BOOL)isDataSetUntitled { return m_DataSetUntitled; } - (BOOL)isDataSetEdited { return m_DataSetEdited; } - (int)rowsSelected { return [oDataSetTable numberOfSelectedRows]; } - (int)columnsSelected { return [oDataSetTable numberOfSelectedColumns]; } - (void)logEntry:(NSString *)aString forMethod:(NSString *)method { NSString * title = [NSString stringWithFormat:@"[%@] ", [[self window] title]]; NSDictionary * attr = [NSDictionary dictionaryWithObject:[NSColor blueColor] forKey:NSForegroundColorAttributeName]; NSAttributedString * str = [[NSAttributedString alloc] initWithString:title attributes:attr]; [m_Controller appendToLog:str]; [str release]; [m_Controller logEntry:aString forMethod:method]; } - (void)logError:(NSString *)aString forMethod:(NSString *)method { NSDictionary * attr = [NSDictionary dictionaryWithObject:[NSColor redColor] forKey:NSForegroundColorAttributeName]; NSAttributedString * str = [[NSAttributedString alloc] initWithString:@"Error: " attributes:attr]; [m_Controller appendToLog:str]; [str release]; [self logEntry:aString forMethod:method]; } /* NSTableView delegate method */ - (void)tableViewSelectionDidChange:(NSNotification *)aNotification { // TODO } /* NSTableDataSource methods */ - (int)numberOfRowsInTableView:(NSTableView *)aTableView { return (int) ((m_DataSet ? [m_DataSet count] : 0) + 64); } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { if (m_DataSet) if ((rowIndex + 1) < [m_DataSet count]) // the first row in m_DataSet is the column headers (field names) { NSMutableArray * row = (NSMutableArray *) [m_DataSet objectAtIndex:(rowIndex + 1)]; unsigned col = [[aTableColumn identifier] unsignedIntValue]; if (col < [row count]) { return [row objectAtIndex:col]; } } return @""; } @end