/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ /* AbiSource Application Framework * Copyright (C) 1998 AbiSource, Inc. * Copyright (C) 2003, 2009 Hubert Figuiere * * 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. */ #include #include #include #include "ut_assert.h" #include "ut_debugmsg.h" #include "ut_string.h" #include "ut_misc.h" #include "ut_units.h" #include "xap_CocoaDialog_Utilities.h" #include "xap_CocoaDlg_FontChooser.h" #include "xap_CocoaApp.h" #include "xap_CocoaCompat.h" #include "xap_EncodingManager.h" #include "gr_CocoaCairoGraphics.h" // your typographer's standard nonsense latin font phrase #define PREVIEW_ENTRY_DEFAULT_STRING "Lorem ipsum dolor sit amet, consectetaur adipisicing..." /*****************************************************************/ XAP_Dialog * XAP_CocoaDialog_FontChooser::static_constructor(XAP_DialogFactory * pFactory, XAP_Dialog_Id dlgid) { XAP_CocoaDialog_FontChooser * p = new XAP_CocoaDialog_FontChooser(pFactory,dlgid); return p; } XAP_CocoaDialog_FontChooser::XAP_CocoaDialog_FontChooser(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id dlgid) : XAP_Dialog_FontChooser(pDlgFactory,dlgid), m_bSuperScriptInitialValue(false), m_bSubScriptInitialValue(false), m_currentFamily(NULL), m_dlg(nil) { // } XAP_CocoaDialog_FontChooser::~XAP_CocoaDialog_FontChooser(void) { FREEP(m_currentFamily); DELETEP(m_pGraphics); } /*****************************************************************/ void XAP_CocoaDialog_FontChooser::strikeoutChanged(bool value) { m_bStrikeout = value; m_bChangedStrikeOut = !m_bChangedStrikeOut; setFontDecoration(m_bUnderline,m_bOverline,m_bStrikeout,m_bTopline,m_bBottomline); updatePreview(); } void XAP_CocoaDialog_FontChooser::underlineChanged(bool value) { m_bUnderline = value; m_bChangedUnderline = !m_bChangedUnderline; setFontDecoration(m_bUnderline,m_bOverline,m_bStrikeout,m_bTopline,m_bBottomline); updatePreview(); } void XAP_CocoaDialog_FontChooser::overlineChanged(bool value) { m_bOverline = value; m_bChangedOverline = !m_bChangedOverline; setFontDecoration(m_bUnderline,m_bOverline,m_bStrikeout,m_bTopline,m_bBottomline); updatePreview(); } void XAP_CocoaDialog_FontChooser::superscriptChanged(bool value) { m_bSuperScript = value; m_bSubScript = false; [m_dlg setSubscript:m_bSubScript]; m_bChangedSuperScript = (m_bSuperScript != m_bSuperScriptInitialValue); m_bChangedSubScript = (m_bSubScript != m_bSubScriptInitialValue ); setSuperScript(m_bSuperScript); setSubScript (m_bSubScript); updatePreview(); } void XAP_CocoaDialog_FontChooser::subscriptChanged(bool value) { m_bSuperScript = false; m_bSubScript = value; [m_dlg setSuperscript:m_bSuperScript]; m_bChangedSuperScript = (m_bSuperScript != m_bSuperScriptInitialValue); m_bChangedSubScript = (m_bSubScript != m_bSubScriptInitialValue ); setSuperScript(m_bSuperScript); setSubScript (m_bSubScript); updatePreview(); } void XAP_CocoaDialog_FontChooser::transparencyChanged(bool value) { bool bTrans = value; if(bTrans) { addOrReplaceVecProp("bgcolor","transparent"); UT_DEBUGMSG (("Update background color")); } updatePreview(); } void XAP_CocoaDialog_FontChooser::fontRowChanged(void) { NSString *fontFamily; fontFamily = [m_dlg selectedFont]; FREEP(m_currentFamily); m_currentFamily = g_strdup([fontFamily UTF8String]); addOrReplaceVecProp("font-family",m_currentFamily); updatePreview(); } void XAP_CocoaDialog_FontChooser::styleRowChanged(int rowNumber) { if (rowNumber == 0) { addOrReplaceVecProp("font-style","normal"); addOrReplaceVecProp("font-weight","normal"); } else if (rowNumber == 1) { addOrReplaceVecProp("font-style","italic"); addOrReplaceVecProp("font-weight","normal"); } else if (rowNumber == 2) { addOrReplaceVecProp("font-style","normal"); addOrReplaceVecProp("font-weight","bold"); } else if (rowNumber == 3) { addOrReplaceVecProp("font-style","italic"); addOrReplaceVecProp("font-weight","bold"); } else { UT_ASSERT(0); } updatePreview(); } void XAP_CocoaDialog_FontChooser::sizeRowChanged(void) { NSString* fontSize; static char szFontSize[60]; fontSize = [m_dlg selectedSize]; snprintf(szFontSize, sizeof(szFontSize), "%spt", (gchar *)XAP_EncodingManager::fontsizes_mapping.lookupByTarget([fontSize UTF8String])); addOrReplaceVecProp("font-size",(gchar *)szFontSize); updatePreview(); } /*! Change the color for the property. \param color the NSColor \param attr the CSS attribute \param buf the buf to store the color (static in the caller) */ void XAP_CocoaDialog_FontChooser::_colorChanged(NSColor * color, const gchar * attr, char * buf) { XAP_CGFloat r,g,b,a; color = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; [color getRed:&r green:&g blue:&b alpha:&a]; snprintf(buf, 7, "%02x%02x%02x", (unsigned int) (r * (float) 255.0), (unsigned int) (g * (float) 255.0), (unsigned int) (b * (float) 255.0)); addOrReplaceVecProp(attr,(gchar *)buf); updatePreview(); } /*! Called when text color has been changed in the widget */ void XAP_CocoaDialog_FontChooser::fgColorChanged(void) { static char buf_color[8]; _colorChanged([m_dlg textColor], "color", buf_color); } /*! Called when text background color has been changed in the widget */ void XAP_CocoaDialog_FontChooser::bgColorChanged(void) { static char buf_color[8]; _colorChanged([m_dlg bgColor], "bgcolor", buf_color); } void XAP_CocoaDialog_FontChooser::runModal(XAP_Frame * /*pFrame*/) { UT_ASSERT(m_pApp); m_dlg = [[XAP_CocoaDialog_FontChooserController alloc] initFromNib]; // used similarly to convert between text and numeric arguments [m_dlg setXAPOwner:this]; // build the dialog NSWindow * window = [m_dlg window]; UT_ASSERT(window); // freeze updates of the preview _createGC([m_dlg preview]); event_previewClear(); // Set the defaults in the list boxes according to dialog data [m_dlg selectFont:(char*)getVal("font-family").c_str()]; [m_dlg selectStyle:(char*)getVal("font-style").c_str() withWeight:(char*)getVal("font-weight").c_str()]; [m_dlg selectSize:(char*)getVal("font-size").c_str()]; // Set color in the color selector const std::string sColor = getVal("color"); if (!sColor.empty()) { UT_RGBColor c; UT_parseColor(sColor.c_str(), c); NSColor *color = GR_CocoaCairoGraphics::_utRGBColorToNSColor(c); [m_dlg setTextColor:color]; } else { [m_dlg setTextColor:[[NSColor blackColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]]; } // Set color in the color selector const std::string sBGCol = getVal("bgcolor"); if (!sBGCol.empty() && strcmp(sBGCol.c_str(),"transparent") != 0) { UT_RGBColor c; UT_parseColor(sBGCol.c_str(), c); NSColor *color = GR_CocoaCairoGraphics::_utRGBColorToNSColor(c); [m_dlg setBgColor:color]; } else { [m_dlg setBgColor:[[NSColor whiteColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]]; } // set the strikeout and underline check buttons [m_dlg setStrikeout:m_bStrikeout]; [m_dlg setUnderline:m_bUnderline]; [m_dlg setOverline:m_bOverline]; m_bSuperScriptInitialValue = m_bSuperScript; m_bSubScriptInitialValue = m_bSubScript; [m_dlg setSuperscript:m_bSuperScript]; [m_dlg setSubscript:m_bSubScript]; updatePreview(); // Run the dialog [NSApp runModalForWindow:window]; [m_dlg discardXAP]; [m_dlg close]; [m_dlg release]; m_dlg = nil; UT_DEBUGMSG(("FontChooserEnd: Family[%s%s] Size[%s%s] Weight[%s%s] Style[%s%s] Color[%s%s] Underline[%d%s] StrikeOut[%d%s]\n", getVal("font-family").c_str(), ((m_bChangedFontFamily) ? "(chg)" : ""), getVal("font-size").c_str(), ((m_bChangedFontSize) ? "(chg)" : ""), getVal("font-weight").c_str(), ((m_bChangedFontWeight) ? "(chg)" : ""), getVal("font-style").c_str(), ((m_bChangedFontStyle) ? "(chg)" : ""), getVal("color").c_str(), ((m_bChangedColor) ? "(chg)" : ""), m_bUnderline, ((m_bChangedUnderline) ? "(chg)" : ""), m_bStrikeout, ((m_bChangedStrikeOut) ? "(chg)" : ""))); } bool XAP_CocoaDialog_FontChooser::getEntryString(const char ** string) { UT_ASSERT(string); // Maybe this will be editable in the future, if one wants to // hook up a mini formatter to the entry area. Probably not. *string = PREVIEW_ENTRY_DEFAULT_STRING; return true; } void XAP_CocoaDialog_FontChooser::updatePreview(void) { // if we don't have anything yet, just ignore this request if (!m_pGraphics) { return; } // if a font has been set since this dialog was launched, draw things with it const char * entryString; if (!getEntryString(&entryString)) { return; } UT_UCSChar * unicodeString = NULL; UT_UCS4_cloneString_char(&unicodeString, entryString); event_previewExposed(unicodeString); FREEP(unicodeString); } void XAP_CocoaDialog_FontChooser::_okAction(void) { m_answer = XAP_Dialog_FontChooser::a_OK; [NSApp stopModal]; } void XAP_CocoaDialog_FontChooser::_cancelAction(void) { m_answer = XAP_Dialog_FontChooser::a_CANCEL; [NSApp stopModal]; } /* callbacks to create / release the GR_Graphics when the window is loaded / released */ void XAP_CocoaDialog_FontChooser::_createGC(XAP_CocoaNSView* owner) { NSSize size; GR_CocoaCairoAllocInfo ai(owner); m_pGraphics = static_cast(XAP_App::getApp()->newGraphics(ai)); size = [owner bounds].size; _createFontPreviewFromGC(m_pGraphics, lrintf(size.width), lrintf(size.height)); } void XAP_CocoaDialog_FontChooser::_deleteGC(void) { DELETEP(m_pGraphics); m_pGraphics = NULL; } @implementation XAP_CocoaDialog_FontChooserController - (id)initFromNib { return [super initWithWindowNibName:@"xap_CocoaDlg_FontChooser"]; } -(void)discardXAP { if (_xap) { _xap->_deleteGC(); _xap = NULL; } } -(void)dealloc { [m_sizeDataSource release]; [m_stylesDataSource release]; [m_fontDataSource release]; [super dealloc]; } - (void)setXAPOwner:(XAP_Dialog *)owner { _xap = dynamic_cast(owner); } -(void)windowDidLoad { if (_xap) { const XAP_StringSet * pSS = _xap->getApp()->getStringSet(); LocalizeControl([self window], pSS, XAP_STRING_ID_DLG_UFS_FontTitle); LocalizeControl(_okBtn, pSS, XAP_STRING_ID_DLG_OK); LocalizeControl(_cancelBtn, pSS, XAP_STRING_ID_DLG_Cancel); LocalizeControl(_fontLabel, pSS, XAP_STRING_ID_DLG_UFS_FontLabel); LocalizeControl(_styleLabel, pSS, XAP_STRING_ID_DLG_UFS_StyleLabel); LocalizeControl(_sizeLabel, pSS, XAP_STRING_ID_DLG_UFS_SizeLabel); LocalizeControl(_effectLabel, pSS, XAP_STRING_ID_DLG_UFS_EffectsFrameLabel); LocalizeControl(_strikeButton, pSS, XAP_STRING_ID_DLG_UFS_StrikeoutCheck); LocalizeControl(_underlineButton, pSS, XAP_STRING_ID_DLG_UFS_UnderlineCheck); LocalizeControl(_overlineButton, pSS, XAP_STRING_ID_DLG_UFS_OverlineCheck); LocalizeControl(_strikeButton, pSS, XAP_STRING_ID_DLG_UFS_StrikeoutCheck); // LocalizeControl(_strikeButton, pSS, XAP_STRING_ID_DLG_UFS_EncodingLabel); LocalizeControl(_superscriptButton, pSS, XAP_STRING_ID_DLG_UFS_SuperScript); LocalizeControl(_subscriptButton, pSS, XAP_STRING_ID_DLG_UFS_SubScript); LocalizeControl(_textColorLabel, pSS, XAP_STRING_ID_DLG_UFS_ColorTab); LocalizeControl(_textHighlightColorLabel, pSS, XAP_STRING_ID_DLG_UFS_BGColorTab); LocalizeControl(_noHighlightColorButton, pSS, XAP_STRING_ID_DLG_UFS_TransparencyCheck); m_fontDataSource = [[XAP_StringListDataSource alloc] init]; [m_fontDataSource loadFontList]; [_fontList setDataSource:m_fontDataSource]; [_fontList setDelegate:self]; m_stylesDataSource = [[XAP_StringListDataSource alloc] init]; UT_UTF8String label; pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_StyleRegular, label); [m_stylesDataSource addCString:label.utf8_str()]; pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_StyleItalic, label); [m_stylesDataSource addCString:label.utf8_str()]; pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_StyleBold, label); [m_stylesDataSource addCString:label.utf8_str()]; pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_StyleBoldItalic, label); [m_stylesDataSource addCString:label.utf8_str()]; [_styleList setDataSource:m_stylesDataSource]; [_styleList setDelegate:self]; m_sizeDataSource = [[XAP_StringListDataSource alloc] init]; { int sz = XAP_EncodingManager::fontsizes_mapping.size(); for (int i = 0; i < sz; ++i) { char* str = (char*)XAP_EncodingManager::fontsizes_mapping.nth2(i); if (str) { [m_sizeDataSource addString:[NSString stringWithUTF8String:str]]; } else { NSLog(@"attempting to add NULL to string data source (%s:%d)", __FILE__, __LINE__); } } } [_sizeList setDataSource:m_sizeDataSource]; [_sizeList setDelegate:self]; } else { NSLog(@"Loaded Windows without XAP (%s:%d)", __FILE__, __LINE__); } if ([[NSColorPanel sharedColorPanel] isVisible]) { [_textColorWell activate:YES]; } } -(IBAction)okAction:(id)sender { UT_UNUSED(sender); [[NSColorPanel sharedColorPanel] orderOut:self]; static_cast(_xap)->_okAction(); } -(IBAction)cancelAction:(id)sender { UT_UNUSED(sender); [[NSColorPanel sharedColorPanel] orderOut:self]; static_cast(_xap)->_cancelAction(); } -(IBAction)colorWellAction:(id)sender { if (sender == _textColorWell) { _xap->fgColorChanged(); } else if (sender == _textHighlightColorWell) { _xap->bgColorChanged(); } } -(IBAction)underlineAction:(id)sender { static_cast(_xap)->underlineChanged ([(NSControl*)sender intValue] == NSOffState ? 0 : 1); } -(IBAction)overlineAction:(id)sender { static_cast(_xap)->overlineChanged ([(NSControl*)sender intValue] == NSOffState ? 0 : 1); } -(IBAction)strikeoutAction:(id)sender { static_cast(_xap)->strikeoutChanged ([(NSControl*)sender intValue] == NSOffState ? 0 : 1); } -(IBAction)superscriptAction:(id)sender { static_cast(_xap)->superscriptChanged ([(NSControl*)sender intValue] == NSOffState ? 0 : 1); } -(IBAction)subscriptAction:(id)sender { static_cast(_xap)->subscriptChanged ([(NSControl*)sender intValue] == NSOffState ? 0 : 1); } -(IBAction)transparentAction:(id)sender { static_cast(_xap)->transparencyChanged ([(NSControl*)sender intValue] == NSOffState ? 0 : 1); } - (void)tableViewSelectionDidChange:(NSNotification *)aNotification { id obj = [aNotification object]; if (obj == _fontList) { _xap->fontRowChanged(); } else if (obj == _styleList) { int idx; idx = [_styleList selectedRow]; _xap->styleRowChanged(idx); } else if (obj == _sizeList) { _xap->sizeRowChanged(); } } - (XAP_CocoaNSView*)preview; { return _preview; } -(void)setStrikeout:(bool)value { [_strikeButton setState:(value ? NSOnState : NSOffState)]; } -(void)setUnderline:(bool)value { [_underlineButton setState:(value ? NSOnState : NSOffState)]; } -(void)setOverline:(bool)value { [_overlineButton setState:(value ? NSOnState : NSOffState)]; } -(void)setSuperscript:(bool)value { [_superscriptButton setState:(value ? NSOnState : NSOffState)]; } -(void)setSubscript:(bool)value { [_subscriptButton setState:(value ? NSOnState : NSOffState)]; } -(void)selectFont:(char*)value { if (value) { int idx = [(XAP_StringListDataSource*)[_fontList dataSource] rowWithCString:value]; if (idx >= 0) { [_fontList selectRow:idx byExtendingSelection:NO]; [_fontList scrollRowToVisible:idx]; } } else { UT_DEBUGMSG(("selectFont: called with NULL value\n")); [_fontList setAllowsEmptySelection:YES]; [_fontList deselectAll:nil]; return; } } -(NSString*)selectedFont { int idx = [_fontList selectedRow]; return [[(XAP_StringListDataSource*)[_fontList dataSource] array] objectAtIndex:idx]; } -(void)selectSize:(char*)value { int idx; char sizeString[60]; if (value == NULL) { UT_DEBUGMSG(("selectSize: called with NULL value\n")); [_sizeList setAllowsEmptySelection:YES]; [_sizeList deselectAll:nil]; return; } snprintf(sizeString, 60, "%s", std_size_string(UT_convertToPoints(value))); idx = [(XAP_StringListDataSource*)[_sizeList dataSource] rowWithCString:(char *)XAP_EncodingManager::fontsizes_mapping.lookupBySource(sizeString)]; if (idx >= 0) { [_sizeList selectRow:idx byExtendingSelection:NO]; [_sizeList scrollRowToVisible:idx]; } } -(NSString*)selectedSize { int idx = [_sizeList selectedRow]; return [[(XAP_StringListDataSource*)[_sizeList dataSource] array] objectAtIndex:idx]; } -(void)selectStyle:(char*)style withWeight:(char*)weight { // this is pretty messy int st = 0; if (!style || !weight) { st = -1; } else if (!g_ascii_strcasecmp(style, "normal") && !g_ascii_strcasecmp(weight, "normal")) { st = 0; } else if (!g_ascii_strcasecmp(style, "italic") && !g_ascii_strcasecmp(weight, "normal")) { st = 1; } else if (!g_ascii_strcasecmp(style, "normal") && !g_ascii_strcasecmp(weight, "bold")){ st = 2; } else if (!g_ascii_strcasecmp(style, "italic") && !g_ascii_strcasecmp(weight, "bold")) { st = 3; } else { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); } if (st != -1) { [_styleList selectRow:st byExtendingSelection:NO]; [_styleList scrollRowToVisible:st]; } } -(NSColor*)textColor { return [_textColorWell color]; } -(void)setTextColor:(NSColor*)color { [_textColorWell setColor:color]; } -(NSColor*)bgColor { return [_textHighlightColorWell color]; } -(void)setBgColor:(NSColor*)color { [_textHighlightColorWell setColor:color]; } @end