Finished spelling dialog resource.
Created code neccesary to operate the dialog correctly under BeOS.

spell.rsrc and should be inserted in /abi/src/wp/main/beos -- needs to 
be marked as binary.
I've included diffs of the files neccesary to hook up these dialogs.

-Christopher
--- /windisk/abiword/abi/src/wp/ap/beos/ap_BeOSDialog_Spell.cpp Wed Jul 26 13:20:02 
2000
+++ ap_BeOSDialog_Spell.cpp     Tue Jul 25 11:26:26 2000
@@ -32,6 +32,40 @@
 
 #include "ut_Rehydrate.h"
 
+// We really shouldn't unlock the window lock, but the redraw when we focus on the 
+next
+// misspelled word will deadlock if we don't..
+
+status_t WaitForDelete(sem_id blocker)
+{
+       status_t        result;
+       thread_id       this_tid = find_thread(NULL);
+       BLooper         *pLoop;
+       BWindow         *pWin = 0;
+
+       pLoop = BLooper::LooperForThread(this_tid);
+       if (pLoop)
+               pWin = dynamic_cast<BWindow*>(pLoop);
+
+       // block until semaphore is deleted (modal is finished)
+       if (pWin) {
+               do {
+                       // update the window periodically
+                       pWin->Unlock(); // Who will know?=)
+                       snooze(100);
+                       pWin->Lock();
+                       
+                       pWin->UpdateIfNeeded();
+                       result = acquire_sem_etc(blocker, 1, B_TIMEOUT, 1000);
+               } while (result != B_BAD_SEM_ID);
+       } else {
+               do {
+                       // just wait for exit
+                       result = acquire_sem(blocker);
+               } while (result != B_BAD_SEM_ID);
+       }
+       return result;
+}
+
 /*****************************************************************/
 
 class SpellWin:public BWindow {
@@ -42,57 +76,380 @@
                virtual bool QuitRequested(void);
                
        private:
-                int                     spin;
                AP_BeOSDialog_Spell     *m_DlgSpell;
+                               
+               void _showMisspelledWord();
+               void _suggestChange();
+               void _toggleChangeButtons(UT_Bool shouldShow);
+               void _change();
+               void _tryAgain();
+               void _changeAll();
+               
+               rgb_color normalText, badText;
+               sem_id modalSem;
 };
 
 SpellWin::SpellWin(BMessage *data) 
-         :BWindow(data) {
-       spin = 1;
+         :BWindow(data)
+{
+
 } 
 
-void SpellWin::SetDlg(AP_BeOSDialog_Spell *dlg) {
+void SpellWin::SetDlg(AP_BeOSDialog_Spell *dlg)
+{
        m_DlgSpell = dlg;
 
+       // As nice as using InterfaceElements is, the app doesn't properly set up
+       // the textRect for our BTextView..
+       BTextView* sentenceView = (BTextView *)FindView("sentencedisplay");
+       BRect frameRect = sentenceView->Bounds();
+       frameRect.InsetBy(5,5);
+       
+       sentenceView->SetTextRect(frameRect);
+               
+       normalText.red = normalText.blue = normalText.green = 0;
+       normalText.alpha = 255;
+
+       badText.red = 255;
+       badText.blue = badText.green = 0;
+       badText.alpha = 255;
+       
+       UT_Bool bRes = m_DlgSpell->nextMisspelledWord();
+       if(!bRes)
+               return;
+               
+       // set initial state
+       m_DlgSpell->makeWordVisible();
+       
+       _showMisspelledWord();
+       
+       // This semaphore ties up the window until after it deletes..
+       modalSem = create_sem(0,"SpellModalSem");
+
        Show();
-       while (spin) { snooze(1); }
-       Hide();
 
-#if 0
-   UT_Bool bRes = nextMisspelledWord();
-   while (bRes) {
-       // show word in main window
-        makeWordVisible(); 
+       WaitForDelete(modalSem);
+}
+
+void SpellWin::_suggestChange()
+{
+       BListView* suggestList = (BListView *)FindView("suggestlist");
+       BTextControl* changeText = (BTextControl *)FindView("changetxt");
+       
+       m_DlgSpell->m_iSelectedRow = suggestList->CurrentSelection();
+       
+       if (!m_DlgSpell->m_Suggestions.count) 
+       {
+               // no change to suggest, ignore it
+               if (m_DlgSpell->m_iSelectedRow != -1)
+                       suggestList->Select(-1);
+       }
+       else
+       {
+               // copy suggestion to edit field
+               UT_ASSERT((m_DlgSpell->m_iSelectedRow > -1));
+
+               BStringItem* selectedItem = (BStringItem 
+*)suggestList->ItemAt(m_DlgSpell->m_iSelectedRow);
+               changeText->SetText(selectedItem->Text());
+       }
+
+}
+
+void SpellWin::_change(void)
+{
+       UT_UCSChar * replace = NULL;
+       BTextControl* changeText = (BTextControl *)FindView("changetxt");
+
+       if (m_DlgSpell->m_iSelectedRow != -1)
+       {
+               replace = m_DlgSpell->m_Suggestions.word[m_DlgSpell->m_iSelectedRow];
+               m_DlgSpell->changeWordWith(replace);
+       }
+       else
+       {
+               UT_UCS_cloneString_char(&replace, changeText->Text());
+               if (!UT_UCS_strlen(replace)) 
+               {
+                       return;
+               }
+               m_DlgSpell->changeWordWith(replace);
+       }
+
+       _tryAgain();
+}
+
+
+void SpellWin::_tryAgain(void)
+{
+       BListView* suggestList = (BListView *)FindView("suggestlist");
+
+       // clear prior suggestions
+       m_DlgSpell->_purgeSuggestions();
+       
+       int32 numItems = suggestList->CountItems();
+       
+       // Clear out the dialog
+       for ( int32 i = 0; i < numItems; i++ )
+       {
+               BListItem* pItem = suggestList->RemoveItem((long int)0);
+               delete pItem;
+       }
+
+       // what's next
+       UT_Bool bRes = m_DlgSpell->nextMisspelledWord();
 
-       // update dialog with new misspelled word info/suggestions
-        //_showMisspelledWord();
+       if (bRes)
+       {
+               // show word in main window
+               m_DlgSpell->makeWordVisible();
 
-        // run into the GTK event loop for this window
-        //gtk_main();
+               // update dialog with new misspelled word info/suggestions
+               _showMisspelledWord();
+       }
+       else
+       {
+               PostMessage(B_QUIT_REQUESTED);
+       }
+}
 
-        //_purgeSuggestions();
+void SpellWin::_changeAll(void)
+{
+       BTextControl* changeText = (BTextControl *)FindView("changetxt");
+       UT_UCSChar * replace = NULL;
+       
+       if (m_DlgSpell->m_iSelectedRow != -1)
+       {
+               replace = (UT_UCSChar*) 
+m_DlgSpell->m_Suggestions.word[m_DlgSpell->m_iSelectedRow];
+               m_DlgSpell->addChangeAll(replace);
+               m_DlgSpell->changeWordWith(replace);
+       }
+       else
+       {
+               UT_UCS_cloneString_char(&replace,changeText->Text());
+               if (!UT_UCS_strlen(replace)) 
+               {
+                       return;
+               }
+                       
+               m_DlgSpell->addChangeAll(replace);
+               m_DlgSpell->changeWordWith(replace);
+       }
+
+       _tryAgain();
+}
 
-        if (m_bCancelled) break;
+void SpellWin::_showMisspelledWord(void)
+{
+       UT_UCSChar *p;
+       UT_uint32 len;
+       char * buf;
+       UT_uint32 sum = 0;
+
+       BTextView* sentenceView = (BTextView *)FindView("sentencedisplay");
+       BListView* suggestList = (BListView *)FindView("suggestlist");
+       
+       sentenceView->SetText("");
+       sentenceView->MakeEditable(true);
+
+       // Run array is 3 long because begin sentence black, misspelled word red, end 
+sentence black..
+       // Note: We need to delete this when we are done..
+       text_run_array* array = (text_run_array *)malloc(sizeof(text_run_array) + 
+sizeof(text_run) * 3);
+       array->count = 3;
+
+       array->runs[0].offset = 0;
+       array->runs[0].font = be_plain_font;
+       array->runs[0].color = normalText;
+       
+       array->runs[1].font = be_bold_font;
+       array->runs[1].color = badText;
+
+       array->runs[2].font = be_plain_font;
+       array->runs[2].color = normalText;
+
+       // insert start of sentence
+
+       p = m_DlgSpell->_getPreWord();
+       len = UT_UCS_strlen(p);
+       if (len)
+       {
+               buf = new char [len + 1];
+               UT_UCS_strcpy_to_char(buf, p);
+               sentenceView->Insert(buf, (long int)len);
+               DELETEP(buf);
+       }
+       FREEP(p);
+       sum += len;
+
+       array->runs[1].offset = sum;
+       
+       p = m_DlgSpell->_getCurrentWord();
+       len = UT_UCS_strlen(p);
+       if (len)
+       {
+               buf = new char [len + 1];
+               UT_UCS_strcpy_to_char(buf, p);
+               sentenceView->Insert(sum, buf, (long int)len);
+               DELETEP(buf);
+       }
+       FREEP(p);
+       sum += len;
+
+       array->runs[2].offset = sum;
+
+       p = m_DlgSpell->_getPostWord();
+       len = UT_UCS_strlen(p);
+       if (len)
+       {
+               buf = new char [len + 1];
+               UT_UCS_strcpy_to_char(buf, p);
+               sentenceView->Insert(sum, buf, (long int)len);
+               DELETEP(buf);
+       }
+       FREEP(p);
+       
+       sentenceView->SetRunArray(0, (long int)sum + len , array);
+       sentenceView->MakeEditable(false);
+
+       // insert suggestions
+       if (!m_DlgSpell->m_Suggestions.count) 
+       {
+               const XAP_StringSet * pSS = m_DlgSpell->m_pApp->getStringSet();
+               BStringItem* emptyItem = new 
+BStringItem(pSS->getValue(AP_STRING_ID_DLG_Spell_NoSuggestions));
+               suggestList->AddItem(emptyItem);
+               m_DlgSpell->m_iSelectedRow = -1;
+               _toggleChangeButtons(UT_FALSE);
+       } 
+       else 
+       {
+               for (int i = 0; i < m_DlgSpell->m_Suggestions.count; i++)
+               {
+                       p = (UT_UCSChar *) m_DlgSpell->m_Suggestions.word[i];
+                       len = UT_UCS_strlen(p);
+                       if (len)
+                       {
+                               buf = new char [len + 1];
+                               UT_UCS_strcpy_to_char(buf, p);
+                               BStringItem* pItem = new BStringItem(buf);
+                               suggestList->AddItem(pItem);
+                               DELETEP(buf);
+                       }
+               }
+
+               m_DlgSpell->m_iSelectedRow = 0;
+               _toggleChangeButtons(UT_TRUE);
+       }
 
-        // get the next unknown word
-        bRes = nextMisspelledWord();                      
-   }
-#endif
+       suggestList->Select(0);
+       _suggestChange();
 }
 
-void SpellWin::DispatchMessage(BMessage *msg, BHandler *handler) {
-       switch(msg->what) {
+void SpellWin::DispatchMessage(BMessage *msg, BHandler *handler) 
+{
+       BTextControl* editSuggest;
+       BListView* suggestList;
+       int32 selIndex;
+       BStringItem* pCurSelItem;
+       
+       switch(msg->what) 
+       {
+       case 'ibut': // ignore button
+               m_DlgSpell->ignoreWord();
+               _tryAgain();
+               break;
+       
+       case 'iabu': // ignore all button.
+               m_DlgSpell->addIgnoreAll();
+               m_DlgSpell->ignoreWord();
+               _tryAgain();
+               break;
+               
+       case 'abut': // add button
+               m_DlgSpell->addToDict();
+               m_DlgSpell->ignoreWord();
+               _tryAgain();
+               break;
+               
+       case 'cbut':
+               _change();
+               break;
+               
+       case 'cabu':
+               _changeAll();
+               break;
+       
+       case 'selc':
+               // Update the current selection in the add box..
+               suggestList = (BListView *)FindView("suggestlist");
+               editSuggest = (BTextControl *)FindView("changetxt");
+       
+               m_DlgSpell->m_iSelectedRow = suggestList->CurrentSelection();
+               selIndex = m_DlgSpell->m_iSelectedRow;
+               
+               pCurSelItem = (BStringItem 
+*)suggestList->ItemAt(m_DlgSpell->m_iSelectedRow);
+       
+               if(pCurSelItem)
+                       editSuggest->TextView()->SetText(pCurSelItem->Text());
+
+               break;
+               
+       case 'invs': // Called when the user double-clicks a suggested word in the 
+spell dialog.
+               suggestList = (BListView *)FindView("suggestlist");
+               if( msg->FindInt32("index" , &selIndex) == B_OK)
+               {
+                       m_DlgSpell->m_iSelectedRow = selIndex;
+                       _change();
+               }
+               break;
+       
+       case 'spmo': // Whenever the user edits the text control.
+
+               // Determine if the user clicked an item in the suggest box.
+               
+               suggestList = (BListView *)FindView("suggestlist");
+               editSuggest = (BTextControl *)FindView("changetxt");
+
+               for(int i = 0; i < suggestList->CountItems(); i ++)
+               {
+                       pCurSelItem = (BStringItem *)suggestList->ItemAt(i);
+
+                       if(strcmp(pCurSelItem->Text() , editSuggest->Text()) == 0)
+                       {
+                               return;;
+                       }
+               }
+               
+               // The user is editing it so, enable the change button.
+               _toggleChangeButtons(UT_TRUE);
+               
+               suggestList->DeselectAll();
+               m_DlgSpell->m_iSelectedRow = -1;
+               
+               break;
+               
        default:
                BWindow::DispatchMessage(msg, handler);
        }
+       
 } 
 
 //Behave like a good citizen
-bool SpellWin::QuitRequested() {
-       spin = 0;
+bool SpellWin::QuitRequested()
+{
+       delete_sem(modalSem);
        return(true);
 }
 
+void SpellWin::_toggleChangeButtons(UT_Bool shouldShow)
+{
+       BButton *change, *changeall;
+       change = (BButton *)FindView("change");
+       changeall = (BButton *)FindView("changeall");
+       
+       if(change)
+               change->SetEnabled(shouldShow);
+       if(changeall)
+               changeall->SetEnabled(shouldShow);
+}
 
 /*****************************************************************/
 
@@ -125,7 +482,7 @@
                 newwin = new SpellWin(&msg);
                 newwin->SetDlg(this);
                 //Take the information here ...
-                newwin->Close();
+                // newwin->Close(); QuitRequested kills this dialog..
         }                
 }
 

BeOS Attributes

--- /windisk/abiword/abi/src/wp/ap/beos/ap_BeOSDialog_Spell.h   Wed Jul 26 13:20:10 
2000
+++ ap_BeOSDialog_Spell.h       Mon Jul 24 15:39:39 2000
@@ -28,6 +28,8 @@
 
 class AP_BeOSDialog_Spell: public AP_Dialog_Spell
 {
+       friend class SpellWin;
+       
  public:
    AP_BeOSDialog_Spell(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id);
    virtual ~AP_BeOSDialog_Spell(void);

BeOS Attributes

spell.rsrc

BeOS Attributes

Reply via email to