diff --git a/mozilla/cmd/macfe/prefs/CAssortedMediators.cp b/mozilla/cmd/macfe/prefs/CAssortedMediators.cp index 709674edeaf..659ef5f2fd6 100644 --- a/mozilla/cmd/macfe/prefs/CAssortedMediators.cp +++ b/mozilla/cmd/macfe/prefs/CAssortedMediators.cp @@ -85,1281 +85,8 @@ extern "C" #include "CMailNewsContext.h" #include "CMailProgressWindow.h" #endif -#endif // MOZ_MAIL_NEWS - -#pragma mark ---CMIMEListPane--- -//====================================== -class CMIMEListPane : public LTable, public LCommander, public LBroadcaster -//====================================== -{ -public: - - enum - { - class_ID = 'MmLP', - msg_SelectionChanged = 'SelĘ', // ioparam = this - msg_DoubleClick = '2Clk' // ioparam = this - }; - - class PrefCellInfo - { - public: - PrefCellInfo(); - PrefCellInfo(CMimeMapper* mapper, CApplicationIconInfo* iconInfo); - - CMimeMapper* fMapper; // The mapper from the preference MIME list - CApplicationIconInfo* fIconInfo; // Information about icon to draw - }; - - // „„ Constructors/destructors/access - - CMIMEListPane(LStream *inStream); - void FinishCreateSelf(); - void BindCellToApplication(TableIndexT row, CMimeMapper * mapper); - CApplicationIconInfo* GetAppInfo(CMimeMapper* mapper); - - // „„ access -//#if defined(QAP_BUILD) -// virtual void QapGetContents(PWCINFO pwc, short *pCount, short max); -// virtual void QapGetListInfo(PQAPLISTINFO pInfo); -// virtual short QapGetListContents(Ptr pBuf, short index); -//#endif - -// void SetContainer( CPrefHelpersContain* container) { fContainer = container; } - void GetCellInfo(PrefCellInfo& cellInfo, int row); - void FreeMappers(); - Boolean MimeTypeExists(CMimeMapper* mapper); - - // „„ Cell selection - void DrawCell( const TableCellT& inCell ); - void SelectCell( const TableCellT& inCell ); - virtual void ClickCell( const TableCellT& inCell, - const SMouseDownEvent& inMouseDown); - - // Drawing - virtual void DrawSelf(); - virtual void HiliteCell(const TableCellT &inCell); - virtual void UnhiliteCell(const TableCellT &inCell); - void ScrollCellIntoFrame(const TableCellT& inCell); - virtual void ActivateSelf(); - - // Events - virtual Boolean HandleKeyPress(const EventRecord &inKeyEvent); - -protected: - CApplicationList mApplList; // List of application and their icons -// CPrefHelpersContain* fContainer; // Containing view - Handle mNetscapeIcon; // Icon for Netscape - Handle mPluginIcon; // Icon for plug-ins -}; // class CMIMEListPane - - -#define msg_LaunchRadio 300 // Launch option changed -#define msg_BrowseApp 301 // Pick a new application -#define msg_FileTypePopup 302 // New file type picked -//msg_EditField // User typed in a field -#define msg_NewMimeType 303 // New Mime type -#define msg_NewMimeTypeOK 305 // Sent by newMimeType dialog window -//#define msg_ClearCell 306 -#define msg_EditMimeType 307 // Edit Mime type -#define msg_DeleteMimeType 308 // Delete Mime type -#define msg_PluginPopup 309 // Pick a plug-in - -//----------------------------------- -CMIMEListPane::CMIMEListPane(LStream *inStream) -//----------------------------------- -: -//fContainer(nil), -mNetscapeIcon(nil), -mPluginIcon(nil), -LTable(inStream) -{ -} - -//----------------------------------- -void CMIMEListPane::FinishCreateSelf() -//----------------------------------- -{ - SetCellDataSize(sizeof(PrefCellInfo)); - - for (TableIndexT i = 1; i <= CPrefs::sMimeTypes.GetCount(); i++) // Insert a row for each mime type - { - CMimeMapper * mime; - CPrefs::sMimeTypes.FetchItemAt(i, &mime); - ThrowIfNil_(mime); - if (!mime->IsTemporary()) - { - CMimeMapper * duplicate = new CMimeMapper(*mime); - PrefCellInfo cellInfo; - InsertRows(1, i, &cellInfo); - BindCellToApplication(i, duplicate); - } - } - - // Cache a handle to the Navigator application icon - CApplicationIconInfo* netscapeInfo = mApplList.GetAppInfo(emSignature); - ThrowIfNil_(netscapeInfo); - ThrowIfNil_(netscapeInfo->fDocumentIcons); - mNetscapeIcon = netscapeInfo->fApplicationIcon; - - // Cache a handle to the standard plug-in icon - LArrayIterator iterator(*(netscapeInfo->fDocumentIcons)); - CFileType* fileInfo; - while (iterator.Next(&fileInfo)) - { - if (fileInfo->fIconSig == emPluginFile) - { - mPluginIcon = fileInfo->fIcon; - break; - } - } - - LTable::FinishCreateSelf(); - - // Set latent subcommander of supercommander of supercommander, which is the - // view that contains the scroller of this table, to table -// if( GetSuperCommander()->GetSuperCommander() ) -// (GetSuperCommander()->GetSuperCommander())->SetLatentSub(this); - LCommander::SwitchTarget(this); -} - - -CApplicationIconInfo* CMIMEListPane::GetAppInfo(CMimeMapper* mapper) -{ - return mApplList.GetAppInfo(mapper->GetAppSig(), mapper); -} - -/* -#if defined(QAP_BUILD) -void -CMIMEListPane::QapGetContents(PWCINFO pwc, short *pCount, short max) -{ - QapAddViewItem(pwc, pCount, WT_ASSIST_ITEM, WC_LIST_BOX); -} - -void -CMIMEListPane::QapGetListInfo(PQAPLISTINFO pInfo) -{ - TableIndexT outRows, outCols; - ControlHandle ctlHandle; - LScroller *scroller; - LStdControl *VSBar; - ControlHandle ctlhVSBar; - - if (pInfo == nil) - return; - - scroller = (LScroller *)((this->GetSuperView())->GetSuperView())->FindPaneByID(12501); - VSBar = scroller->GetVScrollbar(); - ctlhVSBar = VSBar->GetMacControl(); - - GetTableSize(outRows, outCols); - - pInfo->itemCount = (short)outRows; - pInfo->topIndex = (mFrameLocation.v - mImageLocation.v) / mRowHeight; - pInfo->itemHeight = mRowHeight; - pInfo->visibleCount = 8; - pInfo->vScroll = nil; - pInfo->isMultiSel = false; - pInfo->isExtendSel = false; - pInfo->hasText = true; -} - -short -CMIMEListPane::QapGetListContents(Ptr pBuf, short index) -{ - TableCellT sTblCell, currentCell; - PrefCellInfo theData; - Ptr pLimit; - char str[256]; - short count = 0, len = 0; - Uint32 uiSize; - - pLimit = pBuf + *(long *)pBuf; - - switch (index) - { - case QAP_INDEX_ALL: - sTblCell.row = 1; - sTblCell.col = 1; - do - { - GetCellData(sTblCell, (void *)&theData); - - CStr255 description = theData.fMapper->GetDescription(); - if (description.IsEmpty()) - description = theData.fMapper->GetMimeName(); - - if (pBuf + 3 >= pLimit) - break; - - count++; - - *(unsigned short *)pBuf = sTblCell.row - 1; - - GetSelectedCell(currentCell); - - if (currentCell.row == sTblCell.row) - *(unsigned short *)pBuf |= 0x8000; - - pBuf += sizeof(short); - - strcpy(str, (char *)description); - len = strlen(str) + 1; - - if (pBuf + len >= pLimit) - break; - - strcpy(pBuf, str); - pBuf += len; - sTblCell.row++; - } - while (sTblCell.row <= mRows); - - break; - - case QAP_INDEX_SELECTED: - GetSelectedCell(sTblCell); - if (sTblCell.row <= mRows) - { - GetCellData(sTblCell, (void *)&theData); - - CStr255 description = theData.fMapper->GetDescription(); - if (description.IsEmpty()) - description = theData.fMapper->GetMimeName(); - - if (pBuf + 3 >= pLimit) - break; - - count++; - - *(unsigned short *)pBuf = (sTblCell.row - 1) | 0x8000; - - pBuf += sizeof(short); - - strcpy(str, (char *)description); - len = strlen(str) + 1; - - if (pBuf + len >= pLimit) - break; - - strcpy(pBuf, str); - pBuf += len; - } - break; - - default: - sTblCell.row = index + 1; - sTblCell.col = 1; - - if (sTblCell.row <= mRows) - { - GetCellData(sTblCell, (void *)&theData); - - CStr255 description = theData.fMapper->GetDescription(); - if (description.IsEmpty()) - description = theData.fMapper->GetMimeName(); - - if (pBuf + 3 >= pLimit) - break; - - count++; - - *(unsigned short *)pBuf = sTblCell.row - 1; - - - GetSelectedCell(currentCell); - - if (currentCell.row == sTblCell.row) - *(unsigned short *)pBuf |= 0x8000; - - - pBuf += sizeof(short); - - strcpy(str, (char *)description); - len = strlen(str) + 1; - - if (pBuf + len >= pLimit) - break; - - strcpy(pBuf, str); - } - break; - } - return count; -} #endif -*/ -// Sets cell data to values of the mapper -void -CMIMEListPane::BindCellToApplication(TableIndexT row, CMimeMapper* mapper) -{ - CApplicationIconInfo* appInfo = GetAppInfo(mapper); - - // Now figure out the extensions from the netlib - PrefCellInfo cellInfo(mapper, appInfo); - TableCellT cell; - cell.row = row; - cell.col = 1; - SetCellData(cell, &cellInfo); -} - -void -CMIMEListPane::ActivateSelf() -{ - if (triState_On == mVisible) - { - LTable::ActivateSelf(); - } -} - - -void -CMIMEListPane::DrawSelf() -{ - RgnHandle localUpdateRgnH = GetLocalUpdateRgn(); - Rect updateRect = (**localUpdateRgnH).rgnBBox; - DisposeRgn(localUpdateRgnH); - - { - StColorState saveTheColor; - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF}; - RGBBackColor(&white); - EraseRect(&updateRect); - } - - LTable::DrawSelf(); -} - - -void CMIMEListPane::HiliteCell(const TableCellT &inCell) -{ - if (triState_On == mVisible) - { - StColorState saveTheColor; - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF}; - RGBBackColor(&white); - - LTable::HiliteCell(inCell); - } -} - - -void CMIMEListPane::UnhiliteCell(const TableCellT &inCell) -{ - if (triState_On == mVisible) - { - StColorState saveTheColor; - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF}; - RGBBackColor(&white); - - LTable::UnhiliteCell(inCell); - } -} - - - -#define offsetTable 7 -#define offsetTextTop 15 -#define offsetMimeType (offsetTable + 0) -#define offsetIcon (offsetTable + 166) -#define offsetHandler (offsetIcon + 24) -#define widthMimeType (offsetIcon - offsetMimeType - 5) - -void CMIMEListPane::DrawCell(const TableCellT &inCell) -{ - Rect cellFrame; - - if (FetchLocalCellFrame(inCell, cellFrame)) - { - ::PenPat( &(UQDGlobals::GetQDGlobals()->gray) ); - ::MoveTo(cellFrame.left, cellFrame.bottom-1); - ::LineTo(cellFrame.right, cellFrame.bottom-1); - ::PenPat( &(UQDGlobals::GetQDGlobals()->black) ); - - PrefCellInfo cellInfo; - GetCellData(inCell, &cellInfo); - UTextTraits::SetPortTextTraits(10000); // HACK - - // Draw mime type - CStr255 description = cellInfo.fMapper->GetDescription(); - if (description.IsEmpty()) - description = cellInfo.fMapper->GetMimeName(); - short result = ::TruncString(widthMimeType, description, smTruncMiddle); - ::MoveTo(offsetMimeType, cellFrame.top+offsetTextTop); - ::DrawString(description); - - // Draw the icon - CMimeMapper::LoadAction loadAction = cellInfo.fMapper->GetLoadAction(); - if (loadAction == CMimeMapper::Launch || loadAction == CMimeMapper::Plugin || loadAction == CMimeMapper::Internal) - { - Rect r; - r.left = offsetIcon; - r.top = cellFrame.top + 2; - r.right = r.left + 16; - r.bottom = r.top + 16; - - Handle iconHandle; - if (loadAction == CMimeMapper::Plugin) - iconHandle = mPluginIcon; - else if (loadAction == CMimeMapper::Internal) - iconHandle = mNetscapeIcon; - else - iconHandle = cellInfo.fIconInfo->fApplicationIcon; - XP_ASSERT(iconHandle); - - if (iconHandle) - { - if (loadAction == CMimeMapper::Launch && !(cellInfo.fIconInfo->fApplicationFound)) - ::PlotIconSuite(&r, atHorizontalCenter, ttDisabled, iconHandle); - else - ::PlotIconSuite(&r, atHorizontalCenter, ttNone, iconHandle); - } - } - - // Draw the handler name - ::MoveTo(offsetHandler, cellFrame.top+offsetTextTop); - switch (loadAction) - { - case CMimeMapper::Save: - ::DrawString(*GetString(SAVE_RESID)); - break; - case CMimeMapper::Unknown: - ::DrawString(*GetString(UNKNOWN_RESID)); - break; - case CMimeMapper::Internal: - ::DrawString(*GetString(INTERNAL_RESID)); - break; - case CMimeMapper::Launch: - ::DrawString(cellInfo.fMapper->GetAppName()); - break; - case CMimeMapper::Plugin: - ::DrawString(cellInfo.fMapper->GetPluginName()); - break; - } - } -} - - -// Returns PrefCellInfo for the given cell -void CMIMEListPane::GetCellInfo(PrefCellInfo& cellInfo, int row) -{ - TableCellT cell; - cell.row = row; - cell.col = 1; - GetCellData(cell, &cellInfo); -} - -void CMIMEListPane::FreeMappers() -{ - TableCellT cell; - cell.col = 1; - PrefCellInfo cellInfo; - for (int i=1; i<= mRows; i++) - { - cell.row = i; - GetCellData(cell, &cellInfo); - delete cellInfo.fMapper; - } -} - -Boolean CMIMEListPane::MimeTypeExists(CMimeMapper* mapper) -{ - TableCellT cell; - cell.col = 1; - PrefCellInfo cellInfo; - for (int i=1; i<= mRows; i++) - { - cell.row = i; - GetCellData(cell, &cellInfo); - if (cellInfo.fMapper != mapper && - cellInfo.fMapper->GetMimeName() == mapper->GetMimeName()) - return true; - } - return false; -} - -// -// Scroll the view as little as possible to move the specified cell -// entirely within the frame. Currently we only handle scrolling -// up or down a single line (when the selection moves because of -// and arrow key press). -// -void CMIMEListPane::ScrollCellIntoFrame(const TableCellT& inCell) -{ - // Compute bounds of specified cell in image coordinates - Int32 cellLeft = 0; - Int32 cellRight = 1; - Int32 cellBottom = inCell.row * mRowHeight - 2; - Int32 cellTop = cellBottom - mRowHeight + 2; - - if (ImagePointIsInFrame(cellLeft, cellTop) && - ImagePointIsInFrame(cellRight, cellBottom)) - { - return; // Cell is already within Frame - } - else - { - if (cellTop + mImageLocation.v < mFrameLocation.v) - ScrollImageTo(cellLeft, cellTop, true); // Scroll up - else - ScrollPinnedImageBy(0, mRowHeight, true); // Scroll down - } -} - -Boolean CMIMEListPane::HandleKeyPress(const EventRecord &inKeyEvent) -{ - Char16 theChar = inKeyEvent.message & charCodeMask; - Boolean handled = false; - - TableIndexT tableRows; - TableIndexT tableCols; - TableCellT currentCell; - GetSelectedCell(currentCell); - GetTableSize(tableRows, tableCols); - - switch (theChar) - { - case char_UpArrow: - currentCell.row--; - if (currentCell.row >= 1) - { - SelectCell(currentCell); - ScrollCellIntoFrame(currentCell); - } - handled = true; - break; - - case char_DownArrow: - currentCell.row++; - if (currentCell.row <= tableRows) - { - SelectCell(currentCell); - ScrollCellIntoFrame(currentCell); - } - handled = true; - break; - - case char_PageUp: - case char_PageDown: - case char_Home: - case char_End: - default: - handled = LCommander::HandleKeyPress(inKeyEvent); - } - - return handled; -} - -// called by table -void CMIMEListPane::SelectCell(const TableCellT &inCell) -{ -// fContainer->SelectCell(inCell); - LTable::SelectCell(inCell); - BroadcastMessage(msg_SelectionChanged, this); -} - -void -CMIMEListPane::ClickCell(const TableCellT &inCell, const SMouseDownEvent& inMouseDown) -{ - LTable::ClickCell(inCell, inMouseDown); - if (GetClickCount() > 1) - { - BroadcastMessage(msg_DoubleClick, this); - } -} - - -CMIMEListPane::PrefCellInfo::PrefCellInfo(CMimeMapper * mapper, CApplicationIconInfo * iconInfo) -{ - fMapper = mapper; - fIconInfo = iconInfo; -} - -CMIMEListPane::PrefCellInfo::PrefCellInfo() -{ - fMapper = NULL; - fIconInfo = NULL; -} - -#pragma mark ---CEditMIMEWindow--- -//====================================== -class CEditMIMEWindow : public LGADialogBox -//====================================== -{ -public: - enum { class_ID = 'EMMW' }; - - CEditMIMEWindow(LStream* inStream); - virtual ~CEditMIMEWindow(); - - virtual void ListenToMessage(MessageT inMessage, void* ioParam); - - void SetCellInfo(CMIMEListPane::PrefCellInfo&); - void SetMimeTable(CMIMEListPane* table) { mMIMETable = table; } - CMIMEListPane::PrefCellInfo& - GetCellInfo() { return mCellInfo; } - Boolean Modified() { return mModified; } - -protected: - virtual void FinishCreateSelf(); - -private: - void SyncAllControls(); - void SyncTextControls(); - void SyncRadioControlValues(); - void SyncInternalControl(); - void SyncApplicationControls(Boolean mimeTypeChanged); - void SyncPluginControls(Boolean mimeTypeChanged); - void BuildPluginMenu(); - void BuildPluginList(); - void DeletePluginList(); - void BuildFileTypeMenu(); - - Boolean mInitialized; // Initialized with fCellInfo yet? - Boolean mModified; // Have any MIMEs been modified? - CMIMEListPane *mMIMETable; // Scrolling table of MIME types - CMIMEListPane::PrefCellInfo - mCellInfo; // Data for selected item - char** mPluginList; // Null-terminated array of plug-in names - uint32 mPluginCount; // Number of plug-ins in array - - LGAPopup *mFileTypePopup; - LGAPopup *mPluginPopup; - CGAEditBroadcaster *mDescriptionEditField; - CGAEditBroadcaster *mTypeEditField; - CGAEditBroadcaster *mExtensionEditField; - LGARadioButton *mRadioSave; - LGARadioButton *mRadioLaunch; - LGARadioButton *mRadioInternal; - LGARadioButton *mRadioUnknown; - LGARadioButton *mRadioPlugin; -// CFilePicker *mAppPicker; - LCaption *mAppName; - LButton *mAppButton; -// LCaption *mAppMenuLabel; -}; // class CEditMIMEWindow -enum -{ - eNormalTextTraits = 12003, - eGrayTextTraits = 12008, - eDescriptionField = 12507, - eMIMETypeField, - eSuffixes, - eCommunicatorRButton, - ePluginRButton, - ePluginPopupMenu, - eApplicationRButton, - eApplicationNameCaption, - eChooseApplicationButton, - eFileTypePopupMenu, - eSaveRButton, - eUnknownRButton -}; - -//----------------------------------- -CEditMIMEWindow::CEditMIMEWindow(LStream* inStream): -//----------------------------------- - LGADialogBox(inStream), - mMIMETable(nil), - mModified(false), - mInitialized(false), - mPluginList(nil), - mPluginCount(0) -{ -} - - -//----------------------------------- -CEditMIMEWindow::~CEditMIMEWindow() -//----------------------------------- -{ - DeletePluginList(); -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::FinishCreateSelf: -// Fiddle around with a few of our subviews once they've been created. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::FinishCreateSelf() -{ - // Cache pointers to all the controls - mFileTypePopup = (LGAPopup *)FindPaneByID(eFileTypePopupMenu); - XP_ASSERT(mFileTypePopup); - - mPluginPopup = (LGAPopup *)FindPaneByID(ePluginPopupMenu); - XP_ASSERT(mPluginPopup); - - mDescriptionEditField = (CGAEditBroadcaster *)FindPaneByID(eDescriptionField); - XP_ASSERT(mDescriptionEditField); - - mTypeEditField = (CGAEditBroadcaster *)FindPaneByID(eMIMETypeField); - XP_ASSERT(mTypeEditField); - - mExtensionEditField = (CGAEditBroadcaster *)FindPaneByID(eSuffixes); - XP_ASSERT(mExtensionEditField); - - mRadioSave = (LGARadioButton *)FindPaneByID(eSaveRButton); - XP_ASSERT(mRadioSave); - - mRadioLaunch = (LGARadioButton *)FindPaneByID(eApplicationRButton); - XP_ASSERT(mRadioLaunch); - - mRadioInternal = (LGARadioButton *)FindPaneByID(eCommunicatorRButton); - XP_ASSERT(mRadioInternal); - - mRadioUnknown = (LGARadioButton *)FindPaneByID(eUnknownRButton); - XP_ASSERT(mRadioUnknown); - - mRadioPlugin = (LGARadioButton *)FindPaneByID(ePluginRButton); - XP_ASSERT(mRadioPlugin); - -// mAppPicker = (CFilePicker *)FindPaneByID(eApplicationFilePicker); -// XP_ASSERT(mAppPicker); - - mAppName = (LCaption *)FindPaneByID(eApplicationNameCaption); - XP_ASSERT(mAppName); - - mAppButton = (LButton *)FindPaneByID(eChooseApplicationButton); - XP_ASSERT(mAppButton); - -// mAppMenuLabel = (LCaption *)FindPaneByID(pref8AppMenuLabel); -// XP_ASSERT(mAppMenuLabel); - - // Text fields cannot become broadcasters automatically because - // LinkListenerToControls expects fields to be descendants of LControl - // C++ vtable gets messed up - mDescriptionEditField->AddListener(this); - mTypeEditField->AddListener(this); - mExtensionEditField->AddListener(this); - - LGADialogBox::FinishCreateSelf(); -} - - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::SetCellInfo: -// After the CPrefHelpersContain creates us it calls this method to provide -// us with the info for the selected cell, which we copy. We can then -// synchronize our controls to the data they display. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::SetCellInfo(CMIMEListPane::PrefCellInfo& cellInfo) -{ - mCellInfo = cellInfo; - SyncAllControls(); - mInitialized = true; -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::DeletePluginList: -// Delete the list of plug-ins. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::DeletePluginList() -{ - if (mPluginList) - { - uint32 index = 0; - - while (mPluginList[index++]) - { - free(mPluginList[index]); - } - free(mPluginList); - mPluginList = nil; - } -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::BuildPluginList: -// Build a list of plug-ins for this MIME type. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::BuildPluginList() -{ - // Delete the old list - DeletePluginList(); - - // Get the new list from XP code - mPluginList = NPL_FindPluginsForType(mCellInfo.fMapper->GetMimeName()); - - // Count how many are in the list - mPluginCount = 0; - if (mPluginList) - { - while (mPluginList[mPluginCount]) - mPluginCount++; - } -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::BuildPluginMenu: -// Build the plug-in menu from the list of plug-ins available for the current -// MIME type. We need to redraw the popup if the plug-in list used to be non- -// empty or is non-empty now. (It's too expensive to try to detect the case -// of the plug-in list getting rebuilt but still containing the same items.) -// --------------------------------------------------------------------------- -void CEditMIMEWindow::BuildPluginMenu() -{ - uint32 oldCount = mPluginCount; - - BuildPluginList(); - - if (oldCount || mPluginCount) - { - SetMenuSizeForLGAPopup(mPluginPopup, mPluginCount); - - MenuHandle menuH = mPluginPopup->GetMacMenuH(); - uint32 index = 0; - uint32 desiredValue = 1; // Default desired value is first item - while (mPluginList[index]) - { - SetMenuItemText(menuH, index+1, CStr255(mPluginList[index])); - ::EnableItem(menuH, index+1); - if (mCellInfo.fMapper->GetPluginName() == mPluginList[index]) - { - desiredValue = index + 1; - } - index++; - } - - // - // If the previously-selected plug-in name is in this list, - // select it; otherwise just select the first item. - // If we didn't change the control value, make sure it - // redraws since the contents of the list have changed. - // - uint32 previousValue = mPluginPopup->GetValue(); - if (desiredValue != previousValue) - { - mPluginPopup->SetValue(desiredValue); - } - else - { - mPluginPopup->Refresh(); - } - } -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::BuildFileTypeMenu: -// Build the file-type menu from the list file types in the application info. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::BuildFileTypeMenu() -{ - CApplicationIconInfo* appInfo = mCellInfo.fIconInfo; - uint32 count = appInfo->GetFileTypeArraySize(); - - if (count) - { - SetMenuSizeForLGAPopup(mFileTypePopup, count); - - MenuHandle menuH = mFileTypePopup->GetMacMenuH(); - uint32 index; - uint32 desiredValue = 1; - for (index = 1; index <= count; index++) - { - CFileType* fileType = appInfo->GetFileType(index); - SetMenuItemText(menuH, index, CStr255(fileType->fIconSig)); - if (fileType->fIconSig == mCellInfo.fMapper->GetDocType()) - { - desiredValue = index; - } - } - - // - // If the previously-selected file type is in this list, - // select it; otherwise just select the first item. - // If we didn't change the control value, make sure it - // redraws since the contents of the list have changed. - // - uint32 previousValue = mFileTypePopup->GetValue(); - if (desiredValue != previousValue) - { - mFileTypePopup->SetValue(desiredValue); - } - else - { - mFileTypePopup->Refresh(); - } - } -} - - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::SyncTextControls: -// Sync the edit text fields with their actual values (only called when -// the window is first created). -// --------------------------------------------------------------------------- -void CEditMIMEWindow::SyncTextControls() -{ - XP_ASSERT(mCellInfo.fMapper != nil); - - // MIME type - CStr255 newValue = mCellInfo.fMapper->GetDescription(); - mDescriptionEditField->SetDescriptor(newValue); - - // MIME type - newValue = mCellInfo.fMapper->GetMimeName(); - mTypeEditField->SetDescriptor(newValue); - - // Extensions - newValue = mCellInfo.fMapper->GetExtensions(); - mExtensionEditField->SetDescriptor(newValue); -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::SyncRadioControlValues: -// Sync the radio buttons with their actual values (only called when -// the window is first created). -// --------------------------------------------------------------------------- -void CEditMIMEWindow::SyncRadioControlValues() -{ - switch (mCellInfo.fMapper->GetLoadAction()) - { - case CMimeMapper::Save: - if (mRadioSave->GetValue() == 0) - { - mRadioSave->SetValue(1); - } - break; - case CMimeMapper::Launch: - if (mRadioLaunch->GetValue() == 0) - { - mRadioLaunch->SetValue(1); - } - break; - case CMimeMapper::Internal: - if (mRadioInternal->GetValue() == 0) - { - mRadioInternal->SetValue(1); - } - break; - case CMimeMapper::Unknown: - if (mRadioUnknown->GetValue() == 0) - { - mRadioUnknown->SetValue(1); - } - break; - case CMimeMapper::Plugin: - if (mRadioPlugin->GetValue() == 0) - { - mRadioPlugin->SetValue(1); - } - break; - } -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::SyncInternalControl: -// Sync up the "Use Netscape" radio button when the MIME type changes. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::SyncInternalControl() -{ - if (CMimeMapper::NetscapeCanHandle(mCellInfo.fMapper->GetMimeName())) - { - mRadioInternal->Enable(); - } - else - { - mRadioInternal->Disable(); - if (mRadioInternal->GetValue() == 1) - { - mRadioInternal->SetValue(0); - mRadioUnknown->SetValue(1); - } - } -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::SyncApplicationControls: -// Sync up the application-related controls when the "Use application" radio -// button changes state, etc. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::SyncApplicationControls(Boolean applicationChanged) -{ - if (applicationChanged) - { - BuildFileTypeMenu(); - } - Boolean enableAppControls = (mCellInfo.fMapper->GetLoadAction() == CMimeMapper::Launch); - - // - // Application name - // - ResIDT oldTraits = mAppName->GetTextTraitsID(); - if (enableAppControls) - { - mAppName->SetTextTraitsID(eNormalTextTraits); // Normal - } - else - { - mAppName->SetTextTraitsID(eGrayTextTraits); // Dimmed - } - if (applicationChanged) - { - mAppName->SetDescriptor(mCellInfo.fMapper->GetAppName()); - } - else if (oldTraits != mAppName->GetTextTraitsID()) - { - mAppName->Refresh(); - } - // - // Application pick button - // - if (enableAppControls) - { - mAppButton->Enable(); - } - else - { - mAppButton->Disable(); - } - // - // Popup label - // -// oldTraits = mAppMenuLabel->GetTextTraitsID(); -// if (enableAppControls) -// { -// mAppMenuLabel->SetTextTraitsID(10000); // Normal -// } -// else -// { -// mAppMenuLabel->SetTextTraitsID(10003); // Dimmed -// } -// if (oldTraits != mAppMenuLabel->GetTextTraitsID()) -// { -// mAppMenuLabel->Refresh(); -// } - // - // Popup enabled state - // - if (enableAppControls && mCellInfo.fIconInfo->GetFileTypeArraySize() > 0) - { - mFileTypePopup->Enable(); - } - else - { - mFileTypePopup->Disable(); - } - // - // File type - // - if (mRadioLaunch->GetValue() == 1) - { - uint32 item = mFileTypePopup->GetValue(); - XP_ASSERT(item > 0); - CFileType* fileType = mCellInfo.fIconInfo->GetFileType(item); - if (fileType) - { - mCellInfo.fMapper->SetDocType(fileType->fIconSig); - } - } -} - - -// --------------------------------------------------------------------------- -// CEditMIMEWindow::SyncPluginControls: -// Sync up the plugin-related controls when the "Use plugin" radio -// button changes state or the MIME type changes. -// --------------------------------------------------------------------------- -void CEditMIMEWindow::SyncPluginControls(Boolean mimeTypeChanged) -{ - if (mimeTypeChanged) - { - BuildPluginMenu(); - } - // - // Plug-in radio button enabled state - // - if (mPluginCount > 0) - { - mRadioPlugin->Enable(); - } - else - { - mRadioPlugin->Disable(); - if (mRadioPlugin->GetValue() == 1) - { -// mRadioPlugin->SetValue(0); - mRadioUnknown->SetValue(1); - mCellInfo.fMapper->SetLoadAction(CMimeMapper::Unknown); - mModified = true; - } - } - - // - // Plug-in popup control enabled state - // - CMimeMapper* mapper = mCellInfo.fMapper; - CMimeMapper::LoadAction loadAction = mapper->GetLoadAction(); - if (loadAction == CMimeMapper::Plugin && mPluginCount > 0) -// if (fCellInfo.fMapper->GetLoadAction() == CMimeMapper::Plugin && fPluginCount > 0) - { - mPluginPopup->Enable(); - } - else - { - mPluginPopup->Disable(); - } - // - // Plug-in name - // - if (mRadioPlugin->GetValue() == 1) - { - uint32 item = mPluginPopup->GetValue(); - XP_ASSERT(item > 0); - if (mPluginList && item > 0 && item <= mPluginCount) - { - char* plugin = mPluginList[item - 1]; // Menu is 1-based, list is 0-based - if (plugin) - mCellInfo.fMapper->SetPluginName(plugin); - } - } - -} - -//----------------------------------- -void CEditMIMEWindow::SyncAllControls() -// Set up the controls in the dialog box (before it's visible) with the -// information from the currently selected cell. -//----------------------------------- -{ - SyncTextControls(); - SyncRadioControlValues(); - SyncInternalControl(); - SyncApplicationControls(true); - SyncPluginControls(true); -} - - -//----------------------------------- -void CEditMIMEWindow::ListenToMessage(MessageT inMessage, void */*ioParam*/) -// Process a message from the MIME types dialog -//----------------------------------- -{ - if (!mInitialized) - { - return; - } - switch (inMessage) - { - // Pick a handler - case eSaveRButton: - if (mRadioSave->GetValue() == 1) - { - mCellInfo.fMapper->SetLoadAction(CMimeMapper::Save); - } - mModified = TRUE; - break; - case eApplicationRButton: - if (mRadioLaunch->GetValue() == 1) - { - mCellInfo.fMapper->SetLoadAction(CMimeMapper::Launch); - } - SyncApplicationControls(false); - mModified = TRUE; - break; - case eCommunicatorRButton: - if (mRadioInternal->GetValue() == 1) - { - mCellInfo.fMapper->SetLoadAction(CMimeMapper::Internal); - } - mModified = TRUE; - break; - case eUnknownRButton: - if (mRadioUnknown->GetValue() == 1) - { - mCellInfo.fMapper->SetLoadAction(CMimeMapper::Unknown); - } - mModified = TRUE; - break; - case ePluginRButton: - if (mRadioPlugin->GetValue() == 1) - { - mCellInfo.fMapper->SetLoadAction(CMimeMapper::Plugin); - } - SyncPluginControls(false); - mModified = TRUE; - break; - // Pick a new application - case eChooseApplicationButton: - { - StandardFileReply reply; - CFilePicker::DoCustomGetFile(reply, CFilePicker::Applications, FALSE); // Pick app - if (reply.sfGood) - { - // set mappers properties from the app - FInfo finderInfo; - OSErr err = FSpGetFInfo(&reply.sfFile, &finderInfo); - mCellInfo.fMapper->SetAppSig(finderInfo.fdCreator); - mCellInfo.fMapper->SetAppName(reply.sfFile.name); - mCellInfo.fIconInfo = mMIMETable->GetAppInfo(mCellInfo.fMapper); - SyncApplicationControls(true); // App changed - mModified = TRUE; - } - break; - } - - // Change the file type - case eFileTypePopupMenu: - { - SyncApplicationControls(false); - mModified = TRUE; - break; - } - - // Change the plug-in - case ePluginPopupMenu: - { - SyncPluginControls(false); - mModified = TRUE; - break; - } - - // Edit some text - case msg_EditField: - { - CStr255 newText; - - // Commit description - mDescriptionEditField->GetDescriptor(newText); - mCellInfo.fMapper->SetDescription(newText); - - // Commit type - mTypeEditField->GetDescriptor(newText); - if (newText != mCellInfo.fMapper->GetMimeName()) - { - mCellInfo.fMapper->SetMimeType(newText); - SyncPluginControls(true); // Plug-in choices depend on MIME type - SyncInternalControl(); // "Use Netscape" radio depends on MIME type - } - - // Commit the extensions - mExtensionEditField->GetDescriptor(newText); - mCellInfo.fMapper->SetExtensions(newText); - - mModified = TRUE; - break; - } - - case msg_OK: - break; - case msg_Cancel: - break; - default: - break; - } -} #pragma mark ---CEditFieldControl--- //====================================== @@ -1891,6 +618,11 @@ enum eUseCurrentButton }; +enum +{ + eExpireLinksDialog = 1060, + eClearDiskCacheDialog = 1065 +}; CBrowserMainMediator::CBrowserMainMediator(LStream*) : CPrefsMediator(class_ID) @@ -1936,7 +668,7 @@ void CBrowserMainMediator::ExpireNow() { StPrepareForDialog prepare; - short response = ::CautionAlert(eExpireNowButton, NULL); + short response = ::CautionAlert(eExpireLinksDialog, NULL); if (1 == response) { GH_ClearGlobalHistory(); @@ -2535,255 +1267,7 @@ void CBrowserLanguagesMediator::WritePrefs() mLanguagesLocked); } -enum -{ - eEditTypeDialogResID = 12008, - eHelperScroller = 12501, - eHelperTable, - eHelperNewButton, - eHelperEditButton, - eHelperDeleteButton, - eDownloadFilePicker -}; -CBrowserApplicationsMediator::CBrowserApplicationsMediator(LStream*) -: CPrefsMediator(class_ID) -, mModified(false) -, mMIMETable(nil) -{ -} - -void -CBrowserApplicationsMediator::EditMimeEntry() -{ -// StBlockingDialogHandler theHandler(eEditTypeDialogResID, this); - StDialogHandler theHandler(eEditTypeDialogResID, sWindow->GetSuperCommander()); - CEditMIMEWindow* theDialog = (CEditMIMEWindow*)theHandler.GetDialog(); - XP_ASSERT(theDialog); - UReanimator::LinkListenerToControls(theDialog, theDialog, eEditTypeDialogResID); - theDialog->SetMimeTable(mMIMETable); - - // Get the info that the dialog should display - CMIMEListPane::PrefCellInfo cellInfo; - TableCellT cellToEdit; - mMIMETable->GetSelectedCell(cellToEdit); - mMIMETable->GetCellData(cellToEdit, &cellInfo); - - // Make a copy of the info to edit - CMIMEListPane::PrefCellInfo newInfo; - newInfo.fMapper = new CMimeMapper(*cellInfo.fMapper); - newInfo.fIconInfo = cellInfo.fIconInfo; - theDialog->SetCellInfo(newInfo); - - // Let the user have at it... - theDialog->Show(); - MessageT theMessage = msg_Nothing; - while ((theMessage != msg_Cancel) && (theMessage != msg_OK)) - { - theMessage = theHandler.DoDialog(); - - if (theMessage == msg_OK && - cellInfo.fMapper->GetMimeName() != newInfo.fMapper->GetMimeName() && - mMIMETable->MimeTypeExists(newInfo.fMapper)) - { - ErrorManager::PlainAlert(mPREFS_DUPLICATE_MIME); - theMessage = msg_Nothing; - } - // The CEditMIMEWindow will handle all other messages - } - - // Process the munged data as appropriate - if (theMessage == msg_OK && theDialog->Modified()) - { - delete cellInfo.fMapper; // Delete the old mapper - newInfo = theDialog->GetCellInfo(); // Get the edited info - mMIMETable->SetCellData(cellToEdit, &newInfo); // Write the edited info into the table - mModified = TRUE; // Remember that something changed - mMIMETable->Refresh(); // Let table sync to the new data - } - else - { - delete newInfo.fMapper; // Delete the changed but discarded mapper - newInfo.fMapper = NULL; - } -} - -void -CBrowserApplicationsMediator::NewMimeEntry() -{ -// StBlockingDialogHandler theHandler(eEditTypeDialogResID, this); - StDialogHandler theHandler(eEditTypeDialogResID, sWindow->GetSuperCommander()); - CEditMIMEWindow* theDialog = (CEditMIMEWindow *)theHandler.GetDialog(); - XP_ASSERT(theDialog); - UReanimator::LinkListenerToControls(theDialog, theDialog, eEditTypeDialogResID); - theDialog->SetMimeTable(mMIMETable); - - // Create a new default mapper and put it in the table - CStr255 emptyType = ""; - CMimeMapper* newMapper = CPrefs::CreateDefaultUnknownMapper(emptyType, FALSE); - ThrowIfNil_(newMapper); - ThrowIfNil_(mMIMETable); - CMIMEListPane::PrefCellInfo cellInfo; - mMIMETable->InsertRows(1, 0, &cellInfo); - mMIMETable->BindCellToApplication(1, newMapper); - - TableCellT newCell; - newCell.row = newCell.col = 1; - mMIMETable->GetCellData(newCell, &cellInfo); - theDialog->SetCellInfo(cellInfo); - - // Let the user have at it... - theDialog->Show(); - MessageT theMessage = msg_Nothing; - while ((theMessage != msg_Cancel) && (theMessage != msg_OK)) - { - theMessage = theHandler.DoDialog(); - - if (theMessage == msg_OK && mMIMETable->MimeTypeExists(cellInfo.fMapper)) - { - ErrorManager::PlainAlert(mPREFS_DUPLICATE_MIME); - theMessage = msg_Nothing; - } - // The CEditMimeWindow will handle all other messages - } - - // Process the munged data as appropriate - CMIMEListPane::PrefCellInfo newInfo = theDialog->GetCellInfo(); - if (theMessage == msg_OK && theDialog->Modified()) - { - mModified = TRUE; // Remember that something changed - mMIMETable->SetCellData(newCell, &newInfo); // Write the edited info into the table - mMIMETable->SelectCell(newCell); // Select the new cell - mMIMETable->ScrollImageTo(0, 0, TRUE); - mMIMETable->Refresh(); // Let table sync to the new data - } - else - { - delete newInfo.fMapper; // Delete the discarded mapper - mMIMETable->RemoveRows(1, newCell.row); // Remove the row added to the table - } -} - -void -CBrowserApplicationsMediator::DeleteMimeEntry() -{ - if (ErrorManager::PlainConfirm((const char*) GetCString(DELETE_MIMETYPE))) - { - XP_ASSERT(mMIMETable); - TableCellT cellToDelete; - mMIMETable->GetSelectedCell(cellToDelete); - PrefCellInfo cellInfo; - mMIMETable->GetCellData(cellToDelete, &cellInfo); - - // Instead of freeing the item, add it to a list of deleted mime types - // and at commit time, delete the items from xp pref storage. - mDeletedTypes.LArray::InsertItemsAt(1, LArray::index_Last, &cellInfo.fMapper); - - mModified = TRUE; - - mMIMETable->RemoveRows(1, cellToDelete.row); - - // We want to select the cell immediately after the deleted one. It just so - // happens that its coordinates are now (after deleting), what the cell to - // delete was before. So we just need to select cellToDelete. However, if - // there is no cell after the deleted cell (it was the last one), then we - // just select the last one. - TableIndexT rows, columns; - mMIMETable->GetTableSize(rows, columns); - cellToDelete.row = cellToDelete.row > rows? rows: cellToDelete.row; - mMIMETable->ScrollCellIntoFrame(cellToDelete); - mMIMETable->SelectCell(cellToDelete); - mMIMETable->Refresh(); - } -} - -void -CBrowserApplicationsMediator::ListenToMessage(MessageT inMessage, void *ioParam) -{ - switch (inMessage) - { - case eHelperDeleteButton: - DeleteMimeEntry(); - break; - case eHelperNewButton: - NewMimeEntry(); - break; - case eHelperEditButton: - case CMIMEListPane::msg_DoubleClick: - EditMimeEntry(); - break; - case CMIMEListPane::msg_SelectionChanged: - LButton *deleteButton = (LButton *)FindPaneByID(eHelperDeleteButton); - XP_ASSERT(deleteButton); - LButton *editButton = (LButton *)FindPaneByID(eHelperEditButton); - XP_ASSERT(editButton); - - XP_ASSERT(ioParam); - CMIMEListPane *mimeTable = (CMIMEListPane *)ioParam; - TableCellT cell; - mimeTable->GetSelectedCell(cell); - Boolean inactive; - if (cell.row > 0) - { - PrefCellInfo cellInfo; - mimeTable->GetCellData(cell, &cellInfo); - - inactive = CMimeMapper::NetscapeCanHandle(cellInfo.fMapper->GetMimeName()); - editButton->Enable(); - } - else - { - inactive = true; - editButton->Disable(); - } - if (inactive) - deleteButton->Disable(); - else - deleteButton->Enable(); - break; - default: - CPrefsMediator::ListenToMessage(inMessage, ioParam); - break; - } -} - -void -CBrowserApplicationsMediator::LoadMainPane() -{ - CPrefsMediator::LoadMainPane(); - mMIMETable = (CMIMEListPane *)FindPaneByID(eHelperTable); - XP_ASSERT(mMIMETable); - mMIMETable->AddListener(this); - TableCellT currentCell= {1, 1}; // This has to be done after - mMIMETable->SelectCell(currentCell); // mMIMETable->AddListener(); to set the buttons. -} - -void -CBrowserApplicationsMediator::WritePrefs() -{ - if (mModified) - { - CPrefs::sMimeTypes.DeleteAll(FALSE); - XP_ASSERT(mMIMETable); - TableIndexT rows, cols; - mMIMETable->GetTableSize(rows, cols); - for (int i = 1; i <= rows; i++) - { - CMIMEListPane::PrefCellInfo cellInfo; - mMIMETable->GetCellInfo(cellInfo, i); - - cellInfo.fMapper->WriteMimePrefs(); - CMimeMapper* mapper = new CMimeMapper(*cellInfo.fMapper); - CPrefs::sMimeTypes.InsertItemsAt(1, LArray::index_Last, &mapper); - } - for (Int32 i = 1; i <= mDeletedTypes.GetCount(); i++) - { - CMimeMapper* mapper; - mDeletedTypes.FetchItemAt(i, &mapper); - PREF_DeleteBranch(mapper->GetBasePref()); - } - } -} enum @@ -3023,7 +1507,7 @@ void CAdvancedCacheMediator::ClearDiskCacheNow() if (originalDiskCacheSize) // if the current cache size is zero then do nothing { UDesktop::Deactivate(); - short response = ::CautionAlert(eClearDiskCacheButton, NULL); + short response = ::CautionAlert(eClearDiskCacheDialog, NULL); UDesktop::Activate(); if (1 == response) { @@ -3517,8 +2001,7 @@ void UAssortedPrefMediators::RegisterViewClasses() { RegisterClass_(CEditFieldControl); - RegisterClass_( CEditMIMEWindow); - RegisterClass_( CMIMEListPane); + RegisterClass_(CColorButton); RegisterClass_( CFilePicker); @@ -3532,3 +2015,4 @@ void UAssortedPrefMediators::RegisterViewClasses() RegisterClass_(OneRowLListBox); // added by ftang UPrefControls::RegisterPrefControlViews(); } // CPrefsDialog::RegisterViewClasses + diff --git a/mozilla/cmd/macfe/prefs/CAssortedMediators.h b/mozilla/cmd/macfe/prefs/CAssortedMediators.h index 7c66f91b4f3..9ad008d0180 100644 --- a/mozilla/cmd/macfe/prefs/CAssortedMediators.h +++ b/mozilla/cmd/macfe/prefs/CAssortedMediators.h @@ -199,32 +199,8 @@ class CBrowserLanguagesMediator : public CPrefsMediator LTextColumn *mAddLanguageList; }; -//====================================== -#pragma mark -class CBrowserApplicationsMediator : public CPrefsMediator -//====================================== -{ - public: - enum { class_ID = PrefPaneID::eBrowser_Applications }; - CBrowserApplicationsMediator(LStream*); - virtual ~CBrowserApplicationsMediator() {}; - - virtual void ListenToMessage(MessageT inMessage, void *ioParam); - - virtual void LoadMainPane(); - virtual void WritePrefs(); - private: - Boolean mModified; // Have any MIMEs been modified - CMIMEListPane* mMIMETable; // Scrolling table of MIME types - CMimeList mDeletedTypes; - - void EditMimeEntry(); - void NewMimeEntry(); - void DeleteMimeEntry(); -}; - -#ifdef EDITOR +#ifdef EDITOR //====================================== #pragma mark class CEditorMainMediator : public CPrefsMediator diff --git a/mozilla/cmd/macfe/prefs/CMenuTable.cp b/mozilla/cmd/macfe/prefs/CMenuTable.cp index aa908843190..0514d418c68 100644 --- a/mozilla/cmd/macfe/prefs/CMenuTable.cp +++ b/mozilla/cmd/macfe/prefs/CMenuTable.cp @@ -347,7 +347,10 @@ void CMenuTable::HiliteCellActively(const STableCell &inCell, Boolean /* inHilit StColorPenState::Normalize(); UDrawingUtils::SetHiliteModeOn(); - cellFrame.left += (mFirstIndent - 1); + TableIndexT woRow = mCollapsableTree->GetWideOpenIndex(inCell.row); + Uint32 nestingLevel = mCollapsableTree->GetNestingLevel(woRow); + + cellFrame.left += (mFirstIndent +nestingLevel*mLevelIndent ); ::InvertRect(&cellFrame); } } @@ -362,7 +365,10 @@ void CMenuTable::HiliteCellInactively(const STableCell &inCell, Boolean /* inHil StColorPenState saveColorPen; // Preserve color & pen state StColorPenState::Normalize(); - cellFrame.left += (mFirstIndent - 1); + TableIndexT woRow = mCollapsableTree->GetWideOpenIndex(inCell.row); + Uint32 nestingLevel = mCollapsableTree->GetNestingLevel(woRow); + cellFrame.left += (mFirstIndent +nestingLevel*mLevelIndent ); + UDrawingUtils::SetHiliteModeOn(); ::PenMode(srcXor); ::FrameRect(&cellFrame); diff --git a/mozilla/cmd/macfe/prefs/CPrefsDialog.cp b/mozilla/cmd/macfe/prefs/CPrefsDialog.cp index 99beedda660..d0605958e25 100644 --- a/mozilla/cmd/macfe/prefs/CPrefsDialog.cp +++ b/mozilla/cmd/macfe/prefs/CPrefsDialog.cp @@ -49,9 +49,15 @@ #include "uapp.h" +#include "CBrowserApplicationsMediator.h" +#include "CLocationIndependenceMediator.h" +// define this to have the prefs dialog open showing the last pane you +// used, with all twisties expanded +#define PREFS_DIALOG_REMEMBERS_PANE -CPrefsDialog *CPrefsDialog::sThis = nil; +CPrefsDialog* CPrefsDialog::sThis = nil; +PrefPaneID::ID CPrefsDialog::sLastPrefPane = PrefPaneID::eNoPaneSpecified; //----------------------------------- CPrefsDialog::CPrefsDialog() @@ -70,14 +76,18 @@ CPrefsDialog::~CPrefsDialog() // all panes are freed by PowerPlant since they are subcommanders of this dialog... } - //----------------------------------- void CPrefsDialog::EditPrefs( - Expand_T expand, - PrefPaneID::ID pane, - Selection_T selection) + Expand_T expand, + PrefPaneID::ID pane, + Selection_T selection) //----------------------------------- { + +#ifdef PREFS_DIALOG_REMEMBERS_PANE + pane = (pane != PrefPaneID::eNoPaneSpecified) ? pane : sLastPrefPane; +#endif + if (sThis) { // very suspicious @@ -98,6 +108,10 @@ void CPrefsDialog::EditPrefs( XP_Bool useIC; prefResult = PREF_GetBoolPref(useInternetConfigPrefName, &useIC); CPrefsMediator::UseIC(useIC); + + // make sure the prefs cache is empty before we may use it + MPreferenceBase::InitTempPrefCache(); + sThis->DoPrefsWindow(expand, pane, selection); } @@ -167,9 +181,9 @@ void CPrefsDialog::CheckForVCard() //----------------------------------- void CPrefsDialog::DoPrefsWindow( - Expand_T expand, - PrefPaneID::ID pane, - Selection_T selection) + Expand_T expand, + PrefPaneID::ID pane, + Selection_T selection) //----------------------------------- { if (!mWindow) @@ -198,18 +212,17 @@ void CPrefsDialog::DoPrefsWindow( // Now have to collapse the all the rows except appearence // This is icky +#ifndef PREFS_DIALOG_REMEMBERS_PANE mTable->CollapseRow( mTable->FindMessage ( PrefPaneID::eBrowser_Main ) ); - #ifdef MOZ_MAIL_NEWS mTable->CollapseRow( mTable->FindMessage ( PrefPaneID::eMailNews_Main ) ); - #endif // MOZ_MAIL_NEWS #ifdef EDITOR - mTable->CollapseRow( mTable->FindMessage ( PrefPaneID::eEditor_Main ) ); - #endif // EDITOR - #ifdef MOZ_OFFLINE + mTable->CollapseRow( mTable->FindMessage ( PrefPaneID::eEditor_Main ) ); + #endif // Editor + #ifdef MOZ_MAIL_NEWS mTable->CollapseRow( mTable->FindMessage ( PrefPaneID::eOffline_Main ) ); - #endif // MOZ_OFFLINE + #endif // MOZ_MAIL_NEWS mTable->CollapseRow( mTable->FindMessage ( PrefPaneID::eAdvanced_Main ) ); - +#endif mTable->UnselectAllCells(); STableCell initialCell( 1, 1 ); @@ -425,11 +438,21 @@ void CPrefsDialog::ListenToMessage( void CPrefsDialog::Finished() //----------------------------------- { + sLastPrefPane = (PrefPaneID::ID)mTable->GetSelectedMessage(); + mWindow->DoClose(); mWindow = nil; sThis = nil; if (MPreferenceBase::GetWriteOnDestroy()) // the controls wrote themselves + { + // sub-dialogs of the main prefs dialog, e.g. the mail server edit dialog, + // write their prefs into a temporary tree which MPreferenceBase knows about. + // So tell MPreferenceBase to copy these temp prefs into the main prefs, and + // delete that tree. + MPreferenceBase::CopyCachedPrefsToMainPrefs(); + PREF_SavePrefFile(); + } delete this; } @@ -446,8 +469,10 @@ void CPrefsDialog::RegisterViewClasses() RegisterClass_(CBrowserApplicationsMediator); RegisterClass_(CAdvancedCacheMediator); RegisterClass_(CAdvancedProxiesMediator); -#ifdef MOZ_MAIL_NEWS + + CBrowserApplicationsMediator::RegisterViewClasses(); RegisterClass_(CMailNewsIdentityMediator); +#ifdef MOZ_MAIL_NEWS RegisterClass_(CMailNewsMainMediator); RegisterClass_(CMailNewsMessagesMediator); RegisterClass_(CMailNewsOutgoingMediator); @@ -455,6 +480,7 @@ void CPrefsDialog::RegisterViewClasses() RegisterClass_(CMailNewsNewsServerMediator); RegisterClass_(CReceiptsMediator); RegisterClass_(CMailNewsDirectoryMediator); + RegisterClass_(CMailNewsAddressingMediator ); #endif // MOZ_MAIL_NEWS #ifdef EDITOR RegisterClass_(CEditorMainMediator); @@ -466,4 +492,7 @@ void CPrefsDialog::RegisterViewClasses() // And a dialog class: RegisterClass_(CLDAPServerPropDialog); #endif +#ifdef MOZ_LOC_INDEP + RegisterClass_(CLocationIndependenceMediator); +#endif } // CPrefsDialog::RegisterViewClasses diff --git a/mozilla/cmd/macfe/prefs/CPrefsDialog.h b/mozilla/cmd/macfe/prefs/CPrefsDialog.h index e51e2ec6123..a0822c4d416 100644 --- a/mozilla/cmd/macfe/prefs/CPrefsDialog.h +++ b/mozilla/cmd/macfe/prefs/CPrefsDialog.h @@ -67,10 +67,8 @@ class CPrefsDialog #ifdef MOZ_MAIL_NEWS , eExpandOffline = PrefPaneID::eOffline_Main #endif - #ifdef EDITOR , eExpandAdvanced = PrefPaneID::eAdvanced_Main - #endif - + , eExpandAll = PrefPaneID::eNoPaneSpecified }; enum Selection_T @@ -128,7 +126,9 @@ class CPrefsDialog static void CheckForVCard(); void Finished(); - static CPrefsDialog *sThis; + static CPrefsDialog *sThis; + + static PrefPaneID::ID sLastPrefPane; LWindow *mWindow; CPrefsMediator *mCurrentMediator; diff --git a/mozilla/cmd/macfe/prefs/CPrefsMediator.cp b/mozilla/cmd/macfe/prefs/CPrefsMediator.cp index 54aa280a0e4..9e90ecec746 100644 --- a/mozilla/cmd/macfe/prefs/CPrefsMediator.cp +++ b/mozilla/cmd/macfe/prefs/CPrefsMediator.cp @@ -319,8 +319,8 @@ void CPrefsMediator::ListenToMessage(MessageT inMessage, void */*ioParam*/) switch (inMessage) { case eCommitPrefs: - WritePrefs(); MPreferenceBase::SetWriteOnDestroy(true); + WritePrefs(); break; case eCancelPrefs: Canceled(); @@ -615,22 +615,7 @@ void CPrefsMediator::SetPrefWithFolderPopup( const char *prefName, if (!folderName || !*folderName) return; - // make alias - FSSpec fileSpec; - OSErr iErr = CFileMgr::FSSpecFromLocalUnixPath(folderName, &fileSpec); - - if (!iErr) - { - AliasHandle aliasH; - iErr = NewAlias(nil, &fileSpec, &aliasH); - if (!iErr) - { - Size lByteCnt = GetHandleSize((Handle)aliasH); - HLock((Handle)aliasH); - PREF_SetBinaryPref(prefName, *aliasH, lByteCnt); - DisposeHandle((Handle)aliasH); - } - } + PREF_SetPathPref(prefName, folderName, FALSE); } } #endif // MOZ_MAIL_NEWS diff --git a/mozilla/cmd/macfe/prefs/CReceiptsMediator.cp b/mozilla/cmd/macfe/prefs/CReceiptsMediator.cp index 6f642127ff8..fae2c5cabba 100644 --- a/mozilla/cmd/macfe/prefs/CReceiptsMediator.cp +++ b/mozilla/cmd/macfe/prefs/CReceiptsMediator.cp @@ -93,17 +93,35 @@ void CReceiptsMediator::DoCustomDialog() } dialog->Show(); dialog->Select(); + Int32 popupValue[3]; + // Store the dialog popup values in case cancel is hit + for (int32 i =0; i<3; i++ ) + { + LGAPopup* popup = dynamic_cast( dialog->FindPaneByID( i+ 1) ); + XP_ASSERT( popup ); + popupValue[i] = popup->GetValue(); + } MessageT message = msg_Nothing; do { message = mCustomDialogHandler->DoDialog(); - } while (message != msg_OK && message != msg_Cancel); // actually, there's no cancel. + } while (message != msg_OK && message != msg_Cancel); // Use the result. if (message == msg_OK) { // Nothing to do, the prefs are written out when the dialog is destroyed. } + else if ( message == msg_Cancel ) + { + // Restore values from when the dialog was first put up + for ( int32 i =0; i<3; i++ ) + { + LGAPopup* popup = dynamic_cast( dialog->FindPaneByID( i+ 1) ); + XP_ASSERT( popup ); + popup->SetValue(popupValue[i]); + } + } } catch(...) { diff --git a/mozilla/cmd/macfe/prefs/MailNewsMediators.cp b/mozilla/cmd/macfe/prefs/MailNewsMediators.cp index f3bce05f5b9..92427b7efe2 100644 --- a/mozilla/cmd/macfe/prefs/MailNewsMediators.cp +++ b/mozilla/cmd/macfe/prefs/MailNewsMediators.cp @@ -39,13 +39,13 @@ extern "C" #include "InternetConfig.h" #include "CTSMEditField.h" #include "MailNewsAddressBook.h" -#include "UNewFolderDialog.h" #include "CMessageFolder.h" #include "PrefControls.h" #include "CMailNewsContext.h" #include "StGetInfoHandler.h" #include "CNewsSubscriber.h" - +#include "COfflinePicker.h" +#include "UMenuUtils.h" //3P #include #include @@ -57,8 +57,7 @@ extern "C" #include #include -#ifndef MOZ_LITE -#pragma mark ---CLDAPServerPropDialog--- +#ifdef MOZ_MAIL_NEWS //---------------------------------------------------------------------------------------- CLDAPServerPropDialog::CLDAPServerPropDialog( LStream* inStream ) @@ -334,7 +333,7 @@ Boolean CLDAPServerPropDialog::MaxHitsValidationFunc(CValidEditField *maxHits) } return result; } -#endif // MOZ_LITE +#endif // MOZ_MAIL_NEWS enum { @@ -350,6 +349,8 @@ enum eLaunchInternetConfig // currently only used in (MOZ_LITE) }; +#pragma mark - + //---------------------------------------------------------------------------------------- CMailNewsIdentityMediator::CMailNewsIdentityMediator(LStream*) //---------------------------------------------------------------------------------------- @@ -381,6 +382,9 @@ void CMailNewsIdentityMediator::ListenToMessage(MessageT inMessage, void *ioPara #endif // MOZ_LITE #ifndef MOZ_LITE case eUseSigFileBox: + // if IC is being used don't bring up the file picker + if( UseIC() ) + return; CFilePicker *fPicker = (CFilePicker *)FindPaneByID(eSigFilePicker); XP_ASSERT(fPicker); @@ -421,11 +425,34 @@ void CMailNewsIdentityMediator::ListenToMessage(MessageT inMessage, void *ioPara case eInternetConfigBox: Boolean useIC = *(Int32 *)ioParam; UseIC(useIC); -#ifdef MOZ_LITE + UpdateFromIC(); + #ifndef MOZ_MAIL_NEWS + LButton *button = + (LButton *)FindPaneByID(eLaunchInternetConfig); + XP_ASSERT(button); + if (UseIC()) + button->Enable(); + else + button->Disable(); + #endif // MOZ_MAIL_NEWS + + break; + default: + Inherited::ListenToMessage(inMessage, ioParam); + break; + } +} // CMailNewsIdentityMediator::ListenToMessage + +//---------------------------------------------------------------------------------------- +void CMailNewsIdentityMediator::UpdateFromIC() +//---------------------------------------------------------------------------------------- +{ + Boolean useIC = UseIC(); + #ifdef MOZ_LITE LButton *button = (LButton *)FindPaneByID(eLaunchInternetConfig); XP_ASSERT(button); - if (UseIC()) + if ( useIC ) button->Enable(); else button->Disable(); @@ -445,12 +472,31 @@ void CMailNewsIdentityMediator::ListenToMessage(MessageT inMessage, void *ioPara #endif // MOZ_LITE SetEditFieldsWithICPref(kICOrganization, eOrgField); - break; - default: - Inherited::ListenToMessage(inMessage, ioParam); - break; - } -} // CMailNewsIdentityMediator::ListenToMessage + + CFilePicker *picker = + (CFilePicker *)FindPaneByID(eSigFilePicker); + + LCaption* caption = nil; + if( picker ) + caption = (LCaption*)picker->FindPaneByID( 1 ); + + if( picker && caption ) + { + if ( useIC ) + { + picker->Disable(); + LStr255 exampleString(12057, 1 ); + caption->SetDescriptor( exampleString); + } + else + { + picker->Enable(); + picker->SetCaptionForPath( caption, picker->GetFSSpec() ); + } + } +} + + //---------------------------------------------------------------------------------------- void CMailNewsIdentityMediator::LoadPrefs() @@ -464,7 +510,7 @@ void CMailNewsIdentityMediator::LoadPrefs() } } // CMailNewsIdentityMediator::LoadPrefs -#ifndef MOZ_LITE +#ifdef MOZ_MAIL_NEWS enum { @@ -526,47 +572,167 @@ void CMailNewsMessagesMediator::LoadMainPane() SetValidationFunction(eWrapLengthIntegerField, WrapLinesValidationFunc); } -#pragma mark ---CMailNewsOutgoingMediator--- +#pragma mark - + //---------------------------------------------------------------------------------------- CMailNewsOutgoingMediator::CMailNewsOutgoingMediator(LStream*) //---------------------------------------------------------------------------------------- : CPrefsMediator(class_ID) { - Assert_(kNumFolderKinds == UFolderDialogs::num_kinds); - char**p = &mFolderURL[0]; - for (int i = 0; i < kNumFolderKinds; i++) - *p++ = nil; + char** p = &mFolderURL[0]; + for (int i = 0; i < UFolderDialogs::num_kinds; i++,p++) + { + *p = nil; + } +#ifdef HORRIBLE_HACK + Boolean* isDefault = &mFolderIsDefault[0]; + for (int i = 0; i < UFolderDialogs::num_kinds; i++,isDefault++) + *isDefault = false; +#endif // HORRIBLE_HACK } //---------------------------------------------------------------------------------------- CMailNewsOutgoingMediator::~CMailNewsOutgoingMediator() //---------------------------------------------------------------------------------------- { - char**p = &mFolderURL[0]; - for (int i = 0; i < kNumFolderKinds; i++) - XP_FREEIF(*p++); + char** p = &mFolderURL[0]; + for (int i = 0; i < UFolderDialogs::num_kinds; i++,p++) + XP_FREEIF(*p); // BEWARE. The macro XP_FREEIF(*p++) increments three times! } +//---------------------------------------------------------------------------------------- +void CMailNewsOutgoingMediator::FixCaptionNameForFCC(UFolderDialogs::FolderKind kind, const char* mailOrNews) +// For mail/news_fcc, depending on a stupid boolean flag (blah.use_imap_sentmail), +// the prefname changes. This overload figures out the server/local status using the saved pref, +// and calls the other overload, below. +//---------------------------------------------------------------------------------------- +{ + // Check the boolean pref that determines the pref name to be used. + CStr255 prefname = "^0.use_imap_sentmail"; + StringParamText(prefname, mailOrNews); + XP_Bool onServer; + PREF_GetBoolPref(prefname, &onServer); + FixCaptionNameForFCC(kind, mailOrNews, onServer); +} // CMailNewsOutgoingMediator::FixCaptionNameForFCC + +//---------------------------------------------------------------------------------------- +void CMailNewsOutgoingMediator::FixCaptionNameForFCC(UFolderDialogs::FolderKind kind, const char* mailOrNews, Boolean onServer) +// For mail/news_fcc, depending on a stupid boolean flag (blah.use_imap_sentmail), +// the prefname changes. This overload is for the case where the prefs are not saved, and the +// onServer parameter is passed in by the caller. +//---------------------------------------------------------------------------------------- +{ + // Work out which checkbox we have to fix up, and which string to use. This only + // applies to mail_fcc and news_fcc. + PaneIDT checkboxPaneID; + if (kind == UFolderDialogs::mail_fcc) + checkboxPaneID = 'DoMF'; + else if (kind == UFolderDialogs::news_fcc) + checkboxPaneID = 'DoNF'; + else + return; + + // Set the caption pref name of the checkbox accordingly. + CStr255 prefname; + if (onServer) + prefname = "^0.imap_sentmail_path"; + else + prefname = "^0.default_fcc"; + StringParamText(prefname, mailOrNews); + LControl* pb = dynamic_cast(FindPaneByID(checkboxPaneID)); + SignalIf_(!pb); + if (pb) + UPrefControls::NoteSpecialFolderChanged(pb, prefname); +} // CMailNewsOutgoingMediator::FixCaptionNameForFCC + //---------------------------------------------------------------------------------------- void CMailNewsOutgoingMediator::LoadPrefs() //---------------------------------------------------------------------------------------- { + FixCaptionNameForFCC(UFolderDialogs::news_fcc, "news"); + FixCaptionNameForFCC(UFolderDialogs::mail_fcc, "mail"); + + LControl* control = dynamic_cast(FindPaneByID(eMailMailSelfBox) ); + XP_ASSERT( control ); + CStr255 caption; + control->GetDescriptor( caption ); + CStr255 email = FE_UsersMailAddress(); + StringParamText(caption, email); + control->SetDescriptor( caption ); + control = dynamic_cast(FindPaneByID(eMailNewsSelfBox) ); + XP_ASSERT( control ); + control->SetDescriptor( caption ); } // CMailNewsOutgoingMediator::LoadPrefs //---------------------------------------------------------------------------------------- void CMailNewsOutgoingMediator::WritePrefs() //---------------------------------------------------------------------------------------- { - char**p = &mFolderURL[0]; + char** p = &mFolderURL[0]; +#ifdef HORRIBLE_HACK + Boolean* isDefault = &mFolderIsDefault[0]; +#endif // HORRIBLE_HACK CStr255 prefName; - for (int i = 0; i < kNumFolderKinds; i++,p++) + for (int i = 0; i < UFolderDialogs::num_kinds; i++,p++) { + UFolderDialogs::FolderKind kind = (UFolderDialogs::FolderKind)i; if (*p) { - UFolderDialogs::BuildPrefName( - (UFolderDialogs::FolderKind)i, - prefName); - PREF_SetCharPref(prefName, *p); + // For fcc, we must write out the IMAP/Local pref first, so that the prefs name + // will be set correctly in BuildPrefName(), below. + XP_Bool onServer = (XP_Bool)(NET_URL_Type(*p) == IMAP_TYPE_URL); + if (kind == UFolderDialogs::news_fcc) + PREF_SetBoolPref("news.use_imap_sentmail", onServer); + else if (kind == UFolderDialogs::mail_fcc) + PREF_SetBoolPref("mail.use_imap_sentmail", onServer); + Boolean saveAsAlias; + UFolderDialogs::BuildPrefName(kind, prefName, saveAsAlias); +#ifdef HORRIBLE_HACK + if (*isDefault++) + { + // Hack-to-work-around-backend-design-mess #23339: if it's a local folder and it's + // the server, then it's supposed to mean the default folder. But the backend + // doesn't deal with this properly. So append the path here. + CStr255 defaultFolderName; + if (UFolderDialogs::GetDefaultFolderName(kind, defaultFolderName)) + { + StrAllocCat(*p, "/"); + StrAllocCat(*p, (const char*)defaultFolderName); + } + } +#endif // HORRIBLE_HACK +#if DEBUG + if (kind == UFolderDialogs::news_fcc || kind == UFolderDialogs::mail_fcc) + { + Assert_(saveAsAlias == !onServer); + } + else + { + Assert_(!saveAsAlias); + } +#endif + if (saveAsAlias) + { + // For backward compatibility with 4.0x, we have to save this as a path, + // and not a URL in these two cases. + if (kind == UFolderDialogs::news_fcc || kind == UFolderDialogs::mail_fcc) + { + Boolean isURL = NET_URL_Type(*p) == MAILBOX_TYPE_URL; + Assert_(isURL); + if (isURL) + { + char* temp = NET_ParseURL(*p, GET_PATH_PART); + if (temp) + { + XP_FREE(*p); + *p = temp; + } + } + } + PREF_SetPathPref(prefName, *p, FALSE); + } + else + PREF_SetCharPref(prefName, *p); } } } // CMailNewsOutgoingMediator::WritePrefs @@ -576,19 +742,28 @@ void CMailNewsOutgoingMediator::ListenToMessage(MessageT inMessage, void* ioPara //---------------------------------------------------------------------------------------- { UFolderDialogs::FolderKind kind; + PaneIDT descriptionPaneID; // ID of the checkbox or caption corresponding to the button + const char* mailOrNews = nil; // substitution string for the caption prefname. + // We handle the four "choose folder" buttons here. switch (inMessage) { case 'ChMF': kind = UFolderDialogs::mail_fcc; + descriptionPaneID = 'DoMF'; // a checkbox + mailOrNews = "mail"; break; case 'ChNF': kind = UFolderDialogs::news_fcc; + descriptionPaneID = 'DoNF'; // a checkbox + mailOrNews = "news"; break; case 'ChDF': kind = UFolderDialogs::drafts; + descriptionPaneID = 'Drft'; // a caption break; case 'ChTF': kind = UFolderDialogs::templates; + descriptionPaneID = 'Tmpl'; // a caption break; default: Inherited::ListenToMessage(inMessage, ioParam); @@ -598,40 +773,44 @@ void CMailNewsOutgoingMediator::ListenToMessage(MessageT inMessage, void* ioPara const char* curURL = mFolderURL[kind]; if (curURL) curFolder.SetFolderInfo( - ::MSG_GetFolderInfoFromURL(CMailNewsContext::GetMailMaster(), curURL)); + ::MSG_GetFolderInfoFromURL(CMailNewsContext::GetMailMaster(), curURL, false)); CMessageFolder folder = UFolderDialogs::ConductSpecialFolderDialog(kind, curFolder); if (folder.GetFolderInfo() != nil) { URL_Struct* ustruct = ::MSG_ConstructUrlForFolder(nil, folder); + // Set the cached URL string for this folder (used in WritePrefs), and update + // the text on the corresponding special folder checkbox. if (ustruct) { char* newURL = XP_STRDUP(ustruct->address); NET_FreeURLStruct(ustruct); +#ifdef HORRIBLE_HACK + if (folder.IsMailServer() && !folder.IsIMAPMailFolder()) + { + // Hack-to-work-around-backend-design-mess #23339: if it's a local folder and it's + // the server, then it's supposed to mean the default folder. But the backend + // doesn't deal with this properly. + mFolderIsDefault[kind] = true; // so we append the folder name when we write it out. + } +#endif // HORRIBLE_HACK XP_FREEIF(mFolderURL[kind]); mFolderURL[kind] = newURL; - PaneIDT ckID; - switch (inMessage) - { - case 'ChMF': - ckID = 12807; - break; - case 'ChNF': - ckID = 12809; - break; - case 'ChDF': - ckID = 'Drft'; - break; - case 'ChTF': - ckID = 'Tmpl'; - break; - } - LGACheckbox* checkbox = dynamic_cast(FindPaneByID(ckID)); - UPrefControls::NoteSpecialFolderChanged(checkbox, kind, folder); + LPane* paneShowingFolderText = FindPaneByID(descriptionPaneID); + // If it's one of the fcc preferences, we have to make sure the caption is changed + // because the server/local cases are different. The checkbox will update to show + // the folder currently saved for that pref name. + if (mailOrNews) + FixCaptionNameForFCC(kind, mailOrNews, folder.IsIMAPMailFolder()); + // Then we have to update the checkbox caption to reflect the actual folder the + // user has just selected.. + UPrefControls::NoteSpecialFolderChanged(paneShowingFolderText, kind, folder); } } } // CMailNewsOutgoingMediator::ListenToMessage +#pragma mark - + enum { eMoreMailServerOptionsDialogResID = 12003 @@ -687,6 +866,20 @@ Boolean MServerListMediatorMixin::GetHostFromRow( return true; } // CMailNewsMailServerMediator::GetHostFromRow +//---------------------------------------------------------------------------------------- +void MServerListMediatorMixin::SetHostDataForRow(TableIndexT inRow, const CellContents& inCellData, UInt32 inDataSize) const +//---------------------------------------------------------------------------------------- +{ + TableIndexT rowCount, colCount; + mServerTable->GetTableSize(rowCount, colCount); + Assert_(inRow >0 && inRow <= rowCount); + STableCell cell(inRow, 1); + Uint32 cellDataSize = inDataSize; + mServerTable->SetCellData(cell, &inCellData, cellDataSize); + Assert_(cellDataSize >= inDataSize); +} // CMailNewsMailServerMediator::GetHostFromRow + + //---------------------------------------------------------------------------------------- Boolean MServerListMediatorMixin::GetHostFromSelectedRow( CellContents& outCellData, @@ -699,6 +892,90 @@ Boolean MServerListMediatorMixin::GetHostFromSelectedRow( return false; } // CMailNewsMailServerMediator::GetHostFromRow + +//---------------------------------------------------------------------------------------- +Boolean MServerListMediatorMixin::HostExistsElsewhereInTable(const CStr255& inHostName, TableIndexT &ioHostRow) const +//---------------------------------------------------------------------------------------- +{ + Boolean result = false; + + // Is this server name duplicated? + TableIndexT rows, cols; + mServerTable->GetTableSize(rows, cols); + + TableIndexT ignoreRow = ioHostRow; + + for (STableCell cell(1, 1); cell.row <= rows; ++cell.row) + { + if (cell.row == ignoreRow) + continue; + + CellContents contents; + Uint32 cellSize = sizeof(contents); + mServerTable->GetCellData(cell, &contents, cellSize); + + XP_ASSERT(sizeof(CellContents) <= cellSize); // size in PPob is too small! + + if ( inHostName == contents.description ) // we have a duplicate server name. + // Uses CStr == operator, which is case insensitive + { + result = true; + ioHostRow = cell.row; + break; + } + } + + return result; + +} // CMailNewsMailServerMediator::GetHostFromRow + +//---------------------------------------------------------------------------------------- +void MServerListMediatorMixin::DeleteSelectedRow(Boolean inRefresh) +//---------------------------------------------------------------------------------------- +{ + STableCell currentCell = mServerTable->GetFirstSelectedCell(); + if (currentCell.row) + mServerTable->RemoveRows(1, currentCell.row, inRefresh); + +} // CMailNewsMailServerMediator::GetHostFromRow + +//---------------------------------------------------------------------------------------- +void MServerListMediatorMixin::UpdateSelectedRow(const CellContents& inCellData, + Uint32 inDataSize, Boolean inRefresh) +//---------------------------------------------------------------------------------------- +{ + STableCell currentCell = mServerTable->GetFirstSelectedCell(); + if (currentCell.row) + SetHostDataForRow(currentCell.row, inCellData, inDataSize); + + if (inRefresh) + mServerTable->Refresh(); + +} // CMailNewsMailServerMediator::GetHostFromRow + + +//---------------------------------------------------------------------------------------- +void MServerListMediatorMixin::AppendNewRow(const CellContents& inCellData, + Uint32 inDataSize, Boolean inRefresh) +//---------------------------------------------------------------------------------------- +{ + mServerTable->InsertRows(1, LArray::index_Last, &inCellData, inDataSize, inRefresh); + +} // CMailNewsMailServerMediator::GetHostFromRow + +//---------------------------------------------------------------------------------------- +TableIndexT MServerListMediatorMixin::CountRows() +//---------------------------------------------------------------------------------------- +{ + TableIndexT numRows, numCols; + + mServerTable->GetTableSize(numRows, numCols); + + return numRows; + +} // CMailNewsMailServerMediator::GetHostFromRow + + //---------------------------------------------------------------------------------------- void MServerListMediatorMixin::LoadMainPane() //---------------------------------------------------------------------------------------- @@ -769,12 +1046,42 @@ Boolean MServerListMediatorMixin::Listen(MessageT inMessage, void *ioParam) } //---------------------------------------------------------------------------------------- -MServerListMediatorMixin::CellContents::CellContents(const char* inName) +/*static */Boolean MServerListMediatorMixin::ServerIsInCommaSeparatedList( + const char *inServerName, const char *inServerList) //---------------------------------------------------------------------------------------- { - *(CStr255*)&description[0] = inName; + char *listCopy; + char *curToken; + Boolean result = false; + + if (inServerList == NULL) return false; + + listCopy = XP_STRDUP(inServerList); // since strtok modifies it + ThrowIfNil_(listCopy); + + curToken = XP_STRTOK(listCopy, ","); + + while (curToken != NULL) + { + // skip white space + while (*curToken && *curToken == ' ') + curToken ++; + + if (XP_STRCMP(inServerName, curToken) == 0) + { + result = true; + break; + } + + curToken = XP_STRTOK(NULL, ","); + } + + XP_FREE(listCopy); + return result; } +#pragma mark - + //---------------------------------------------------------------------------------------- CServerListMediator::CServerListMediator(PaneIDT inMainPaneID) //---------------------------------------------------------------------------------------- @@ -799,6 +1106,8 @@ void CServerListMediator::ListenToMessage(MessageT inMessage, void *ioParam) CPrefsMediator::ListenToMessage(inMessage, ioParam); } +#pragma mark - + enum { POP3_PORT = 110, /* the iana port for pop3 */ @@ -811,17 +1120,54 @@ CMailNewsMailServerMediator::CMailNewsMailServerMediator(LStream*) //---------------------------------------------------------------------------------------- : CServerListMediator(class_ID) , mServerType(eUnknownServerType) -, mPopServerName(nil) +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF +, mPOPServerName(nil) +#endif { -} +} // CMailNewsMailServerMediator::CMailNewsMailServerMediator //---------------------------------------------------------------------------------------- CMailNewsMailServerMediator::~CMailNewsMailServerMediator() //---------------------------------------------------------------------------------------- { - XP_FREEIF(mPopServerName); +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + XP_FREEIF(mPOPServerName); +#endif } +//---------------------------------------------------------------------------------------- +void CMailNewsMailServerMediator::SetPOPServerName(const CStr255& inName) +//---------------------------------------------------------------------------------------- +{ +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + XP_FREEIF(mPOPServerName); + if (inName.Length() != 0) + mPOPServerName = XP_STRDUP(inName); +#else // Now: + LEditField* editField = dynamic_cast(FindPaneByID('SNAM')); + Assert_(editField); + if (editField) + editField->SetDescriptor(inName); +#endif +} // CMailNewsMailServerMediator::SetPOPServerName + +//---------------------------------------------------------------------------------------- +void CMailNewsMailServerMediator::GetPOPServerName(CStr255& outName) const +//---------------------------------------------------------------------------------------- +{ + outName[0] = 0; +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + if (mPOPServerName) + outName = mPOPServerName; +#else // Now: + LEditField* editField = dynamic_cast(FindPaneByID('SNAM')); + Assert_(editField); + if (!editField) + return; + editField->GetDescriptor(outName); +#endif +} // CMailNewsMailServerMediator::GetPOPServerName + //---------------------------------------------------------------------------------------- Boolean CMailNewsMailServerMediator::NoAtSignValidationFunc(CValidEditField *noAtSign) //---------------------------------------------------------------------------------------- @@ -830,7 +1176,6 @@ Boolean CMailNewsMailServerMediator::NoAtSignValidationFunc(CValidEditField *noA noAtSign->GetDescriptor(value); unsigned char atPos = value.Pos("@"); if (atPos) - // „„„ FIX ME l10n. Why? This is an email address { value.Delete(atPos, 256); // if there is an at sign delete it noAtSign->SetDescriptor(value); // and anything after it @@ -841,6 +1186,29 @@ Boolean CMailNewsMailServerMediator::NoAtSignValidationFunc(CValidEditField *noA return true; } // CMailNewsMailServerMediator::NoAtSignValidationFunc +//---------------------------------------------------------------------------------------- +/* static */ Boolean CMailNewsMailServerMediator::ValidateServerName(const CStr255& inServerName, + Boolean inNewServer, const CServerListMediator* inServerList) +//---------------------------------------------------------------------------------------- +{ + if (inServerName.IsEmpty()) + return false; + + const CMailNewsMailServerMediator *theMediator = dynamic_cast(inServerList); + ThrowIfNil_(theMediator); + + TableIndexT foundRow = LArray::index_Bad; + + // Is this server name duplicated? + if (!inNewServer) + { + STableCell currentCell = theMediator->mServerTable->GetFirstSelectedCell(); // this must be the server we are editing + foundRow = currentCell.row; + } + + return ! theMediator->HostExistsElsewhereInTable(inServerName, foundRow); +} + //---------------------------------------------------------------------------------------- void CMailNewsMailServerMediator::LoadMainPane() //---------------------------------------------------------------------------------------- @@ -853,21 +1221,44 @@ void CMailNewsMailServerMediator::LoadMainPane() void CMailNewsMailServerMediator::LoadPrefs() //---------------------------------------------------------------------------------------- { - int32 serverType = eUnknownServerType; - int32 prefResult = PREF_GetIntPref("mail.server_type", &serverType); - mServerType = (ServerType)serverType; + // Check whether this is the first call on entry (we call LoadPrefs more than once). + if (mServerType == eUnknownServerType) + { + int32 serverType = eUnknownServerType; + int32 prefResult = PREF_GetIntPref("mail.server_type", &serverType); + ThrowIf_(prefResult != PREF_NOERROR); + mServerType = (ServerType)serverType; + } +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF if (mServerType == ePOPServer) { char* value = nil; - int prefResult = PREF_CopyCharPref("network.hosts.pop_server", &value); + int32 prefResult = PREF_CopyCharPref("network.hosts.pop_server", &value); if (prefResult == PREF_NOERROR && value) if (*value) - mPopServerName = value; + mPOPServerName = value; else XP_FREE(value); } +#endif mServersLocked = PREF_PrefIsLocked("network.hosts.pop_server") - || PREF_PrefIsLocked("mail.server_type"); + || PREF_PrefIsLocked("mail.server_type") + || PREF_PrefIsLocked("mail.server_type_on_restart"); + + // Make sure there's a default value + Boolean userNameLocked = PaneHasLockedPref(eMailServerUserNameField); + LEditField* popUserNameField = + dynamic_cast(FindPaneByID(eMailServerUserNameField)); + if (popUserNameField && !userNameLocked) + { + CStr255 username; + popUserNameField->GetDescriptor(username); + if (username.Length() == 0) + { + UGetInfo::GetDefaultUserName(username); + popUserNameField->SetDescriptor(username); + } + } LoadList(); } // CMailNewsMailServerMediator::LoadPrefs @@ -883,18 +1274,22 @@ void CMailNewsMailServerMediator::WritePrefs() void CMailNewsMailServerMediator::UpdateFromIC() //---------------------------------------------------------------------------------------- { + SetEditFieldsWithICPref(kICSMTPHost, eSMTPServerField, true); Boolean userNameLocked = PaneHasLockedPref(eMailServerUserNameField); - if ((userNameLocked && mServersLocked) || !UseIC()) - return; - - LEditField* popUserNameField = - (LEditField*)FindPaneByID(eMailServerUserNameField); + LEditField* popUserNameField = (LEditField*)FindPaneByID(eMailServerUserNameField); Assert_(popUserNameField); + + if ((userNameLocked && mServersLocked) || !UseIC()) + { + popUserNameField->Enable(); + return; + } - Str255 s; - long port; + Str255 s; + long port = POP3_PORT; // port is only returned if the user has a + // :port after the server name in IC. Use POP as default CInternetConfigInterface::GetInternetConfigString( kICMailAccount, s, &port); @@ -914,7 +1309,7 @@ void CMailNewsMailServerMediator::UpdateFromIC() if (server) { server[0] = s[0] - i+1; - s[0] = s[0] - i-1; + s[0] = i-2 ; user = s; } else @@ -925,22 +1320,58 @@ void CMailNewsMailServerMediator::UpdateFromIC() popUserNameField->SetDescriptor(user); popUserNameField->SelectAll(); } + popUserNameField->Disable(); + if (!mServersLocked) { - ClearList(); - XP_FREEIF(mPopServerName); + +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + XP_FREEIF(mPOPServerName); +#endif + if (port == POP3_PORT) { - mPopServerName = XP_STRDUP((const char*)(CStr255)server); - mServerType = ePOPServer; +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + mPOPServerName = XP_STRDUP((const char*)(CStr255)server); +#endif + + // If there is just one server, and there is no inbox yet, + // then set up that server from IC + if (CountRows() <= 1 && CMailNewsContext::UserHasNoLocalInbox()) + { + SetPOPServerName(server); + mServerType = ePOPServer; + + CStr255 serverName(server); + CellContents cellData(serverName); + + if (CountRows() == 0) + AppendNewRow(cellData, sizeof(CellContents)); + else + SetHostDataForRow(1, cellData, sizeof(CellContents)); + } + } else { - PREF_SetCharPref("network.hosts.imap_servers", (const char*)(CStr255)server); - mServerType = eIMAPServer; + // Only change the IMAP server settings if this is a new profile + // Change the cell data to show the new server name, and refresh. + + if (CountRows() <= 1 && CMailNewsContext::UserHasNoLocalInbox()) + { + CStr255 serverName(server); + CellContents cellData(serverName); + + if (CountRows() == 0) + AppendNewRow(cellData, sizeof(CellContents)); + else + SetHostDataForRow(1, cellData, sizeof(CellContents)); + + mServerType = eIMAPServer; + } + } - LoadList(); // rebuild the list, which will now show the new server. } } // CMailNewsMailServerMediator::UpdateFromIC @@ -968,185 +1399,183 @@ void CMailNewsMailServerMediator::AddButton() ErrorManager::PlainAlert(GetPString(MK_POP3_ONLY_ONE + RES_OFFSET)); return; } - CStr255 serverName; // constructor sets to empty string. -#ifdef PRELIMINARY_DIALOG - { // <-----Start scope for name/type dialog - // Put up the dialog to get the name and type... - // If - MPreferenceBase::StWriteOnDestroy setter2(false); - StDialogHandler handler(12011, nil); - LWindow* dialog = handler.GetDialog(); - LGAEditField* nameField = (LGAEditField*)dialog->FindPaneByID('NAME'); - SignalIf_(!nameField); - if (!nameField) - return; - LGARadioButton* popButton = (LGARadioButton*)dialog->FindPaneByID('POP3'); - SignalIf_(!popButton); - if (!popButton) - return; - if (rows == 0) - { - // default for first server is POP - popButton->SetValue(1); - } - else - { - // If they already have a server (and to get here, it must be IMAP) then - // the POP button must be disabled (it is off and enabled by default - // in the resource). - popButton->Disable(); - } - - // Run the dialog - MessageT message = msg_Nothing; - dialog->Show(); - do { - message = handler.DoDialog(); - } while (message != msg_OK && message != msg_Cancel); - if (message == msg_Cancel) - return; - nameField->GetDescriptor(serverName); - mServerType = popButton->GetValue() ? ePOPServer : eIMAPServer; - } // <-----End scope for name/type dialog -#endif // PRELIMINARY_DIALOG - Boolean usePOP = (mServerType == ePOPServer); - if (UGetInfo::ConductMailServerInfoDialog( - serverName, - usePOP, - true)) + + CStr255 serverName; // constructor sets to empty string. + Boolean allowServerTypeEdit = CountRows() == 0; + Boolean usePop = CountRows() == 0; + + // Pass this in as the super commander, because we want to defer the destruction + // of the get info dialog. This is because we don't want to commit its prefs unless the + // user OKs the whole prefs dialog. + if (UGetInfo::ConductMailServerInfoDialog(serverName, usePop, true, true, + allowServerTypeEdit, UGetInfo::kSubDialogOfPrefs, ValidateServerName, this, this)) { - mServerType = usePOP ? ePOPServer : eIMAPServer; - if (usePOP) - { - XP_FREEIF(mPopServerName); - mPopServerName = XP_STRDUP(serverName); - } - LoadPrefs(); - mServerTable->Refresh(); + NoteServerChanges(usePop, serverName); + + CellContents cellData(serverName); + AppendNewRow(cellData, sizeof(CellContents)); } + } // CMailNewsMailServerMediator::AddButton +//---------------------------------------------------------------------------------------- +void CMailNewsMailServerMediator::NoteServerChanges(Boolean inPOP, const CStr255& inServerName) +//---------------------------------------------------------------------------------------- +{ + mServerType = inPOP ? ePOPServer : eIMAPServer; +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + // Since the server info dialog writes out the new stuff immediately, for consistency + // we should make these prefs take effect immediately also. This means that "cancel" + // doesn't, even more. + if (inPOP && inServerName.Length() > 0) + { + SetPOPServerName(inServerName); + int32 prefResult = PREF_SetCharPref("network.hosts.pop_server", inServerName); + ThrowIf_(prefResult < PREF_NOERROR); // PREF_VALUECHANGED = 1 is expected! + } + int32 prefResult = PREF_SetIntPref("mail.server_type_on_restart", mServerType); + ThrowIf_(prefResult < PREF_NOERROR); // PREF_VALUECHANGED = 1 is expected! + // In Nova, we are attempting to make "convert immediately" work! so here goes: + prefResult = PREF_SetIntPref("mail.server_type", mServerType); + ThrowIf_(prefResult < PREF_NOERROR); +#else + // Now. + // Because of historic XP code, you have to have a POP server name, even for IMAP. So + // we might as well always set it to be the same as the IMAP server name. + if (! inServerName.IsEmpty()) + SetPOPServerName(inServerName); // set the invisible server name field. +#endif +} + //---------------------------------------------------------------------------------------- void CMailNewsMailServerMediator::EditButton() // Grab the selected item in the list, create a duplicate of the server associated with that // item and pop up a dialog to edit this server. The OK/Cancel is handled in ObeyCommand(). //---------------------------------------------------------------------------------------- { - CellContents contents; + CellContents contents; GetHostFromSelectedRow(contents, sizeof(CellContents)); Boolean usePOP = (mServerType == ePOPServer); + + // Allow them to edit the server name the first time through after setup. + // Use the doCreate parameter for this. + Boolean isNewServer = false; + Boolean allowServerNameEdit = (usePOP || CMailNewsContext::UserHasNoLocalInbox()); + Boolean allowServerTypeEdit = allowServerNameEdit || (CountRows() == 1); + if (UGetInfo::ConductMailServerInfoDialog( - (CStr255&)contents.description, + contents.description, usePOP, - false)) + isNewServer, + allowServerNameEdit, + allowServerTypeEdit, + UGetInfo::kSubDialogOfPrefs, + (allowServerTypeEdit) ? ValidateServerName : nil, + (allowServerTypeEdit) ? this : nil, + this)) { - mServerType = usePOP ? ePOPServer : eIMAPServer; + NoteServerChanges(usePOP, contents.description); } + + // Update the cell contents to save the handler + UpdateSelectedRow(contents, sizeof(CellContents)); + + } // CMailNewsMailServerMediator::EditButton //---------------------------------------------------------------------------------------- void CMailNewsMailServerMediator::DeleteButton() //---------------------------------------------------------------------------------------- { - CellContents contents; - GetHostFromSelectedRow(contents, sizeof(CellContents)); - if (UStdDialogs::AskOkCancel( - GetPString(MK_MSG_REMOVE_MAILHOST_CONFIRM + RES_OFFSET))) + CellContents cellData; + UInt32 dataSize = sizeof(CellContents); + Boolean showWarning = false; + + GetHostFromSelectedRow(cellData, dataSize); + Assert_(dataSize <= sizeof(CellContents)); + if (! UsingPop()) { - if (UsingPop()) - { - XP_FREEIF(mPopServerName); - } - else - { - ::MSG_DeleteIMAPHost( - CMailNewsContext::GetMailMaster(), - FindMSG_Host((const char*)(CStr255)contents.description)); - } - LoadList(); - mServerTable->Refresh(); - UpdateButtons(); + char *curServerList = nil; + PREF_CopyCharPref("network.hosts.imap_servers", &curServerList); + + showWarning = ServerIsInCommaSeparatedList(cellData.description, curServerList); + XP_FREEIF(curServerList); } + + if (showWarning && !UStdDialogs::AskOkCancel(GetPString(MK_MSG_REMOVE_MAILHOST_CONFIRM + RES_OFFSET))) + return; + + if (UsingPop()) + SetPOPServerName("mail"); + + DeleteSelectedRow(); + + UpdateButtons(); + } // CMailNewsMailServerMediator::DeleteButton -//---------------------------------------------------------------------------------------- -MSG_IMAPHost* CMailNewsMailServerMediator::FindMSG_Host(const char* inHostName) -// Back end will match only on the name, so pass garbage for all the other -// parameters. -//---------------------------------------------------------------------------------------- -{ - return ::MSG_CreateIMAPHost( - CMailNewsContext::GetMailMaster(), - inHostName, - false, // XP_Bool isSecure, - nil, //const char *userName, - false, // XP_Bool checkNewMail, - 0, // int biffInterval, - false, // XP_Bool rememberPassword, - false, // XP_Bool usingSubscription, - false, //XP_Bool overrideNamespaces, - nil, // const char *personalOnlineDir, - nil, // const char *publicOnlineDir, - nil //const char *otherUsersOnlineDir - ); -} - //---------------------------------------------------------------------------------------- void CMailNewsMailServerMediator::LoadList() +// This should only be called once when loading the prefs now //---------------------------------------------------------------------------------------- { ClearList(); if (UsingPop()) { - if (mPopServerName) + CStr255 serverName; + GetPOPServerName(serverName); + + // set empty server name to something useful + Assert_( ! serverName.IsEmpty() ); + + if (! serverName.IsEmpty()) { - CellContents contents(mPopServerName); + CellContents contents(serverName); mServerTable->InsertRows( 1, LArray::index_Last, &contents, sizeof(CellContents), false); } - return; } - char *serverList = nil; - PREF_CopyCharPref("network.hosts.imap_servers", &serverList); - if (serverList) + else { - char *serverPtr = serverList; - while (serverPtr) + char *serverList = nil; + PREF_CopyCharPref("network.hosts.imap_servers", &serverList); + if (serverList) { - char *endPtr = XP_STRCHR(serverPtr, ','); - if (endPtr) - *endPtr++ = '\0'; - CellContents cell(serverPtr); - mServerTable->InsertRows(1, LArray::index_Last, &cell, sizeof(CellContents), false); - serverPtr = endPtr; + char *serverPtr = serverList; + while (serverPtr) + { + char *endPtr = XP_STRCHR(serverPtr, ','); + if (endPtr) + *endPtr++ = '\0'; + CellContents cell(serverPtr); + mServerTable->InsertRows(1, LArray::index_Last, &cell, sizeof(CellContents), false); + serverPtr = endPtr; + } + XP_FREE(serverList); } - XP_FREE(serverList); } + // Refreshing is redundant the first time, but necessary when called after a server info dlg. + mServerTable->Refresh(); } // CMailNewsMailServerMediator::LoadList //---------------------------------------------------------------------------------------- void CMailNewsMailServerMediator::WriteList() -// Here's what we're doing currently. We're allowing the properties dialogs to write out -// their preferences each time they are dismissed. The bad thing about this is that "Cancel" -// on the prefs window will not cancel the results of all the properties dialogs that have -// been made. Instead, we write out the list of IMAP servers. Some of the properties dialogs -// may be orphaned by this, in the sense that we will have written out preferences for servers -// that are not currently on the server list. I think this might be acceptable, since these -// servers will not be used by the back end. Their properties will remain dormant till -// the server is again added to the list. //---------------------------------------------------------------------------------------- { TableIndexT rows, cols; mServerTable->GetTableSize(rows, cols); - if (rows == 0 || mServersLocked) + if (mServersLocked) return; - PREF_SetIntPref("mail.server_type", mServerType); - if (mServerType == ePOPServer) - { - PREF_SetCharPref("network.hosts.pop_server", mPopServerName); - return; - } + + StSpinningBeachBallCursor beachBall; // because making new servers can take some time + +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + if (mServerType == ePOPServer && mPOPServerName && *mPOPServerName) + CStr255 serverName; + GetPOPServerName(serverName); + NoteServerChanges(mServerType, serverName); +#endif #if 0 // There may be no need to do this. The back end updates the list after every // add and delete. @@ -1156,13 +1585,169 @@ void CMailNewsMailServerMediator::WriteList() CellContents contents; Uint32 cellSize = sizeof(contents); mServerTable->GetCellData(cell, &contents, cellSize); - XP_ASSERT(sizeof(cell) == cellSize); + XP_ASSERT(sizeof(CellContents) == cellSize); if (cell.row > 1) - StrAllocCat(serverList, ","); + StrAllocCat(serverList, ","); StrAllocCat(serverList, (const char*)(CStr255)contents.description); } PREF_SetCharPref("network.hosts.imap_servers", serverList); #endif // 0 + + + char *newServerList = XP_STRDUP(""); + char *oldServerList = nil; + PREF_CopyCharPref("network.hosts.imap_servers", &oldServerList); + + if ( UsingPop() ) + { + // the invisible POP server name field in the prefs dialog writes itself out, + // so we have nothing to do but to remove deleted IMAP servers + } + else // IMAP + { + // Here is where we actually write out the changed mail server prefs. + // The strategy is: Get the string of servers from the (old) prefs + // For each server in the string, see if it's in our list + // If not, delete it + // If yes, we need do nothing. + // Servers in our list which are not in the prefs are added. + +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF + // nothing +#else + // Make sure the pop_server does not write out when using IMAP + MPreferenceBase::SetPaneWritePref(sWindow, 'SNAM', false); +#endif + + // The backend has a callback on mail.server_type, which will get called + // when we write out the temp prefs buffer on closing the prefs dialog. + // So, to avoid duplicate hosts being created by this callback, we need + // to set the mail.server_type pref here if necessary. + + if (!oldServerList || !*oldServerList) // no IMAP servers at the moment + { + int prefError = PREF_SetIntPref("mail.server_type", eIMAPServer); + Assert_(prefError == PREF_NOERROR || prefError == PREF_VALUECHANGED); + + // double check + PREF_CopyCharPref("network.hosts.imap_servers", &oldServerList); + } + + for (STableCell cell(1, 1); cell.row <= rows; ++cell.row) + { + CellContents contents; + Uint32 cellSize = sizeof(CellContents); + + mServerTable->GetCellData(cell, &contents, cellSize); + Assert_(sizeof(CellContents) <= cellSize); + + // skip cells with empty text + if (contents.description.Length() == 0) + continue; + + // If the host does not exist, create it + if ( ! ServerIsInCommaSeparatedList(contents.description, oldServerList) ) + { + const char* userNameString = XP_STRDUP(""); // its filled in when the prefs are saved + const char* serverNameString = XP_STRDUP(contents.description); + + // get user name from internet config if necessary + if (UseIC()) + { + CStr255 userAtHostString; + long port; + + CInternetConfigInterface::GetInternetConfigString( kICMailAccount, + userAtHostString, + &port); + if ( !userAtHostString.IsEmpty() ) + { + unsigned char atPos = userAtHostString.Pos("@"); + + if (atPos > 0) + { + userAtHostString[0] = atPos - 1; + + XP_FREEIF(const_cast(userNameString)); + userNameString = XP_STRDUP(userAtHostString); + } + } + } + + try + { + ThrowIfNil_(userNameString); + ThrowIfNil_(serverNameString); + + if (::MSG_GetIMAPHostByName(CMailNewsContext::GetMailMaster(), serverNameString)) + Assert_(false); + else + ::MSG_CreateIMAPHost( + CMailNewsContext::GetMailMaster(), + serverNameString, + false, // XP_Bool isSecure, + userNameString, // const char *userName, + false, // XP_Bool checkNewMail, + 0, // int biffInterval, + false, // XP_Bool rememberPassword, + true, // XP_Bool usingSubscription, + false, // XP_Bool overrideNamespaces, + nil, // const char *personalOnlineDir, + nil, // const char *publicOnlineDir, + nil // const char *otherUsersOnlineDir + ); + } + catch (...) + { + } + XP_FREEIF(const_cast(userNameString)); + XP_FREEIF(const_cast(serverNameString)); + } + + // save the name in the new servers list + if (cell.row > 1) + StrAllocCat(newServerList, ","); + + StrAllocCat(newServerList, (const char*)(CStr255)contents.description); + } + } // using IMAP + + // Now handle deleted servers, which are in the old list but not the new + if (oldServerList) + { + char *serverPtr = oldServerList; + while (serverPtr) + { + + char *endPtr = XP_STRCHR(serverPtr, ','); + if (endPtr) + *endPtr++ = '\0'; + + if ( (*newServerList == 0) || !ServerIsInCommaSeparatedList(serverPtr, newServerList) ) + { + // delete the server + ::MSG_DeleteIMAPHostByName(CMailNewsContext::GetMailMaster(), serverPtr); + } + + serverPtr = endPtr; + } + } + + XP_FREEIF(oldServerList); + XP_FREEIF(newServerList); + + // Did the user delete all their servers? Silly thing, let's make amends + if (rows == 0) + { + // set the pop server name back to the default + SetPOPServerName("mail"); + + // just to make damn sure + MPreferenceBase::SetPaneWritePref(sWindow, 'SNAM', true); + ::PREF_SetIntPref("mail.server_type", ePOPServer); + } + + } // CMailNewsMailServerMediator::WriteList enum @@ -1174,6 +1759,8 @@ enum eNotifyLargeDownloadEditField }; +#pragma mark - + //---------------------------------------------------------------------------------------- CMailNewsNewsServerMediator::CMailNewsNewsServerMediator(LStream*) //---------------------------------------------------------------------------------------- @@ -1236,11 +1823,16 @@ void CMailNewsNewsServerMediator::UpdateFromIC() CInternetConfigInterface::GetInternetConfigString(kICNNTPHost, serverName, &port); // Create or find the host - MSG_NewsHost* host = ::MSG_CreateNewsHost( + char* cserverName = XP_STRDUP(serverName); + if (cserverName) + { + MSG_NewsHost* host = ::MSG_CreateNewsHost( CMailNewsContext::GetMailMaster(), serverName, port == eNNTPSecurePort, port); + XP_FREE(cserverName); + } // Stick it in the list by rebuilding the list LoadList(); } @@ -1260,6 +1852,8 @@ void CMailNewsNewsServerMediator::AddButton() // OK/Cancel is handled in ObeyCommand(). //---------------------------------------------------------------------------------------- { + // This creates the host in the BE straight away. This needs to be re-written so + // that host changes are only committed when the user OKs the prefs dialog CNewsSubscriber::DoAddNewsHost(); LoadPrefs(); mServerTable->Refresh(); @@ -1273,7 +1867,16 @@ void CMailNewsNewsServerMediator::EditButton() { CellContents contents; GetHostFromSelectedRow(contents, sizeof(CellContents)); - UGetInfo::ConductNewsServerInfoDialog(contents.serverData); + + StDialogHandler *dialogHandler = nil; + + if (UGetInfo::ConductNewsServerInfoDialog(contents.serverData, this)) + { + // Fix me. News server changes take place right away, so are not handled like + // the rest of the prefs. See CMailNewsMailServerMediator for the way it + // should work + } + } // CMailNewsNewsServerMediator::EditButton //---------------------------------------------------------------------------------------- @@ -1282,11 +1885,15 @@ void CMailNewsNewsServerMediator::DeleteButton() { CellContents contents; GetHostFromSelectedRow(contents, sizeof(CellContents)); + + // This deletes the host in the BE straight away. This needs to be re-written so + // that host changes are only committed when the user OKs the prefs dialog + ::MSG_DeleteNewsHost(CMailNewsContext::GetMailMaster(), MSG_GetNewsHostFromMSGHost(contents.serverData)); LoadList(); - mServerTable->Refresh(); UpdateButtons(); + } // CMailNewsNewsServerMediator::DeleteButton //---------------------------------------------------------------------------------------- @@ -1363,6 +1970,8 @@ void CMailNewsNewsServerMediator::LoadList() CellContents contents(name, host); mServerTable->InsertRows(1, LArray::index_Last, &contents, sizeof(CellContents), false); } + // Refreshing is redundant the first time, but necessary when called after a server info dlg. + mServerTable->Refresh(); } // CMailNewsNewsServerMediator::LoadList //---------------------------------------------------------------------------------------- @@ -1382,6 +1991,8 @@ enum eLastFirstRButton = 13108 }; +#pragma mark - + //---------------------------------------------------------------------------------------- CMailNewsDirectoryMediator::CMailNewsDirectoryMediator(LStream*) //---------------------------------------------------------------------------------------- @@ -1413,11 +2024,13 @@ void CMailNewsDirectoryMediator::EditButton() //---------------------------------------------------------------------------------------- { // get the data - STableCell currentCell; - CellContents cell; + STableCell currentCell; + CellContents cell; + currentCell = mServerTable->GetFirstSelectedCell(); XP_ASSERT(currentCell.row); - Uint32 cellDataSize = sizeof(CellContents); + + Uint32 cellDataSize = sizeof(CellContents); mServerTable->GetCellData(currentCell, &cell, cellDataSize); XP_ASSERT(cellDataSize == sizeof(CellContents)); @@ -1561,8 +2174,7 @@ Boolean CMailNewsDirectoryMediator::ObeyCommand( CommandT inCommand, void* ioPar DIR_DeleteServer(cell.serverData); // ...then add the new one - cell.description[0] = strlen(newServer->description); - strcpy((char *)&(cell.description[1]), newServer->description); + cell.description = newServer->description; cell.serverData = newServer; mServerTable->SetCellData(currentCell, &cell, cellDataSize); } @@ -1665,9 +2277,12 @@ enum eIncrementMenu, eDaysRButton, eDaysEditField, - eSelectMessageFolderPopup + eSelectMessageButton +// eSelectMessageFolderPopup }; +#pragma mark - + //---------------------------------------------------------------------------------------- COfflineNewsMediator::COfflineNewsMediator(LStream*) //---------------------------------------------------------------------------------------- @@ -1731,14 +2346,74 @@ void COfflineNewsMediator::LoadMainPane() } //---------------------------------------------------------------------------------------- -void COfflineNewsMediator::WritePrefs() +//void COfflineNewsMediator::WritePrefs() +//---------------------------------------------------------------------------------------- +//{ +// CSelectFolderMenu* selectPopup = +// (CSelectFolderMenu*)FindPaneByID(eSelectMessageFolderPopup); +// XP_ASSERT(selectPopup); +// selectPopup->CommitCurrentSelections(); +//} + +//---------------------------------------------------------------------------------------- +void COfflineNewsMediator::ListenToMessage(MessageT inMessage, void *ioParam) //---------------------------------------------------------------------------------------- { - CSelectFolderMenu* selectPopup = - (CSelectFolderMenu*)FindPaneByID(eSelectMessageFolderPopup); - XP_ASSERT(selectPopup); - selectPopup->CommitCurrentSelections(); + switch (inMessage) + { + case eSelectMessageButton: + COfflinePickerWindow::DisplayDialog(); + break; + + default: + Inherited::ListenToMessage(inMessage, ioParam); + break; + } } -#endif // MOZ_LITE +#pragma mark - +//---------------------------------------------------------------------------------------- +void CMailNewsAddressingMediator::LoadPrefs() +//---------------------------------------------------------------------------------------- +{ + + // Build popup menu and data + LGAPopup* popup = dynamic_cast(FindPaneByID( eDirectoryPopup ) ); + Assert_( popup ); + MenuHandle menu = popup->GetMacMenuH(); + mLDAPList = XP_ListNew(); + XP_List *directories = CAddressBookManager::GetDirServerList(); + + DIR_GetLdapServers( directories, mLDAPList ) ; + int16 selected = 0; + int32 i = 0; + if (XP_ListCount(mLDAPList)) + { + DIR_Server *server; + XP_List* listIterator = mLDAPList; + while ( (server = (DIR_Server *)XP_ListNextObject(listIterator) ) != 0 ) + { + + CStr255 description(server->description); + + Int16 index = UMenuUtils::AppendMenuItem( menu, description, true); + if( DIR_TestFlag( server, DIR_AUTO_COMPLETE_ENABLED) ) + selected = index; + } + } + popup->SetPopupMinMaxValues(); + popup->SetValue( selected ); +} + +//---------------------------------------------------------------------------------------- +void CMailNewsAddressingMediator::WritePrefs() +//---------------------------------------------------------------------------------------- +{ + LGAPopup* popup = dynamic_cast(FindPaneByID( eDirectoryPopup )); + Int32 index = popup->GetValue(); + DIR_Server* server = (DIR_Server*)XP_ListGetObjectNum( mLDAPList, index ); + if ( server ) + DIR_SetAutoCompleteEnabled( mLDAPList, server, true ); +} +#endif // MOZ_MAIL_NEWS diff --git a/mozilla/cmd/macfe/prefs/MailNewsMediators.h b/mozilla/cmd/macfe/prefs/MailNewsMediators.h index e22a2c7609e..3cd9dbb34a8 100644 --- a/mozilla/cmd/macfe/prefs/MailNewsMediators.h +++ b/mozilla/cmd/macfe/prefs/MailNewsMediators.h @@ -21,6 +21,7 @@ #include "CPrefsMediator.h" #include "MPreference.h" +#include "UNewFolderDialog.h" #include @@ -29,6 +30,8 @@ class LGACheckbox; class MSG_IMAPHost; class MSG_Host; class CDragOrderTextList; +class StDialogHandler; + //====================================== #pragma mark @@ -46,8 +49,8 @@ class CMailNewsIdentityMediator : public CPrefsMediator virtual void ListenToMessage(MessageT inMessage, void *ioParam); -// virtual void UpdateFromIC(); // don't need this because the IC checkbox is on - // this pane + virtual void UpdateFromIC(); + virtual void LoadPrefs(); }; @@ -89,8 +92,16 @@ class CMailNewsOutgoingMediator : public CPrefsMediator virtual void WritePrefs(); virtual void ListenToMessage(MessageT inMessage, void* ioParam); protected: -#define kNumFolderKinds 4 - char* mFolderURL[kNumFolderKinds]; + void FixCaptionNameForFCC(UFolderDialogs::FolderKind kind, const char* mailOrNews); + void FixCaptionNameForFCC(UFolderDialogs::FolderKind kind, const char* mailOrNews, + Boolean onServer); + + protected: + char* mFolderURL[UFolderDialogs::num_kinds]; + // indexed by UFolderDialogs::FolderKind +#ifdef HORRIBLE_HACK + Boolean mFolderIsDefault[UFolderDialogs::num_kinds]; // HACK +#endif // HORRIBLE_HACK }; // class CMailNewsOutgoingMediator //====================================== @@ -107,28 +118,54 @@ protected: , mServersDirty(false) {} + // note that if you add members to this in inheriting classes, + // you need to change the constructor resources to increase the + // list data size struct CellContents { - CellContents(const char* inName = nil); - Str255 description; + CellContents(const char* inName = nil) + : description(inName) {} + + CStr255 description; }; - Boolean GetHostFromRow( - TableIndexT inRow, - CellContents& outCellData, - UInt32 inDataSize) const; - Boolean GetHostFromSelectedRow( - CellContents& outCellData, - UInt32 inDataSize) const; - virtual void UpdateButtons(); - virtual void AddButton() = 0; - virtual void EditButton() = 0; - virtual void DeleteButton() = 0; - void ClearList(); - virtual void LoadList() = 0; - virtual void WriteList() = 0; - virtual Boolean Listen(MessageT inMessage, void *ioParam); - void LoadMainPane(); + Boolean GetHostFromRow( + TableIndexT inRow, + CellContents& outCellData, + UInt32 inDataSize) const; + Boolean GetHostFromSelectedRow( + CellContents& outCellData, + UInt32 inDataSize) const; + Boolean HostExistsElsewhereInTable( + const CStr255& inHostName, + TableIndexT &outFoundRow) const; + void SetHostDataForRow( + TableIndexT inRow, + const CellContents& inCellData, + UInt32 inDataSize) const; + void AppendNewRow( + const CellContents &inCellData, + Uint32 inDataSize, + Boolean inRefresh = true); + void DeleteSelectedRow( + Boolean inRefresh = true); + void UpdateSelectedRow( + const CellContents &inCellData, + Uint32 inDataSize, + Boolean inRefresh = true); + + virtual TableIndexT CountRows(); + virtual void UpdateButtons(); + virtual void AddButton() = 0; + virtual void EditButton() = 0; + virtual void DeleteButton() = 0; + void ClearList(); + virtual void LoadList() = 0; + virtual void WriteList() = 0; + virtual Boolean Listen(MessageT inMessage, void *ioParam); + void LoadMainPane(); + + static Boolean ServerIsInCommaSeparatedList(const char *inServerName, const char *inServerList); CPrefsMediator* mMediatorSelf; CDragOrderTextList* mServerTable; @@ -169,7 +206,8 @@ class CMailNewsMailServerMediator virtual void LoadPrefs(); virtual void WritePrefs(); - static Boolean NoAtSignValidationFunc(CValidEditField *noAtSign); + static Boolean NoAtSignValidationFunc(CValidEditField *noAtSign); + static Boolean ValidateServerName(const CStr255& inServerName, Boolean inNewServer, const CServerListMediator* inServerList); private: enum ServerType @@ -178,10 +216,18 @@ class CMailNewsMailServerMediator ePOPServer = 0, eIMAPServer = 1 }; - MSG_IMAPHost* FindMSG_Host(const char* inHostName); - Boolean UsingPop() const; // Hope this goes away. + Boolean UsingPop() const; // Hope this goes away. + void NoteServerChanges(Boolean inPOP, const CStr255& inServerName); + void SetPOPServerName(const CStr255& inName); + void GetPOPServerName(CStr255& outName) const; // MServerListMediatorMixin overrides + struct CellContents : public MServerListMediatorMixin::CellContents + { + CellContents() {} + CellContents(const char* inName) + : MServerListMediatorMixin::CellContents(inName) {} + }; virtual void AddButton(); virtual void EditButton(); virtual void DeleteButton(); @@ -191,11 +237,13 @@ class CMailNewsMailServerMediator // Data protected: ServerType mServerType; +#ifdef BEFORE_INVISIBLE_POPSERVER_NAME_EDITFIELD_TRICK_WAS_THOUGHT_OF char* mPopServerName; +#endif }; // class CMailNewsMailServerMediator -#pragma mark //====================================== +#pragma mark class CMailNewsNewsServerMediator //====================================== : public CServerListMediator @@ -221,7 +269,7 @@ class CMailNewsNewsServerMediator CellContents(const char* inName, MSG_Host* inHost) : MServerListMediatorMixin::CellContents(inName) , serverData(inHost) {} - MSG_Host* serverData; + MSG_Host* serverData; }; virtual void AddButton(); virtual void EditButton(); @@ -267,7 +315,7 @@ class CMailNewsDirectoryMediator virtual void AddButton(); virtual void EditButton(); virtual void DeleteButton(); - virtual void LoadList(); + virtual void LoadList(); // only call this once, on creating the list for the first time virtual void WriteList(); virtual void UpdateButtons(); @@ -298,11 +346,43 @@ class COfflineNewsMediator : public CPrefsMediator virtual ~COfflineNewsMediator() {}; virtual void LoadMainPane(); - virtual void WritePrefs(); +// virtual void WritePrefs(); + virtual void ListenToMessage( + MessageT inMessage, + void *ioParam); static Boolean SinceDaysValidationFunc(CValidEditField *sinceDays); }; // class COfflineNewsMediator +#ifdef MOZ_MAIL_NEWS +//====================================== +#pragma mark +class CMailNewsAddressingMediator +//====================================== +: public CPrefsMediator +{ + private: + typedef CPrefsMediator Inherited; + + public: + + enum { class_ID = PrefPaneID::eMailNews_Addressing, eDirectoryPopup = 'DrPu' }; + + CMailNewsAddressingMediator(LStream* ): CPrefsMediator( class_ID ), mLDAPList(NULL) {}; + + virtual ~CMailNewsAddressingMediator() + { + if( mLDAPList ) + XP_ListDestroy( mLDAPList ); + }; + virtual void LoadPrefs(); + virtual void WritePrefs(); + protected: + XP_List* mLDAPList; +}; +#endif // MOZ_MAIL_NEWS + + //====================================== class CLDAPServerPropDialog : public LGADialogBox // This class brings up a dialog for editing the LDAP Server properties (duh). This has diff --git a/mozilla/cmd/macfe/prefs/PrefsPaneIDs.h b/mozilla/cmd/macfe/prefs/PrefsPaneIDs.h index 1835802a573..021fa7a4bf8 100644 --- a/mozilla/cmd/macfe/prefs/PrefsPaneIDs.h +++ b/mozilla/cmd/macfe/prefs/PrefsPaneIDs.h @@ -50,17 +50,24 @@ struct PrefPaneID #ifdef MOZ_MAIL_NEWS , eMailNews_Messages = 12058 , eMailNews_HTMLFormatting = 12072 - , eMailNews_Outgoing = 12073 //<-„„„ Current max. Please move as nec.! + , eMailNews_Outgoing = 12073 , eMailNews_MailServer = 12059 , eMailNews_NewsServer = 12060 , eMailNews_Directory = 12061 , eMailNews_Receipts = 12070 - , eMailNews_SpecialFolders = 12071 + , eMailNews_Addressing = 12071 #endif // MOZ_MAIL_NEWS + #ifdef EDITOR , eEditor_Main = 12062 , eEditor_Publish = 12063 #endif // EDITOR + #ifdef MOZ_LOC_INDEP + , eLocationIndependence = 12074 + , eLocationIndependence_Server = 12075 + , eLocationIndependence_File = 12076 //<-„„„ Current max. Please move as nec.! + #endif // MOZ_LOC_INDEP + #ifdef MOZ_MAIL_NEWS , eOffline_Main = 12064 , eOffline_News = 12065