home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UGroupListCmds.cp < prev    next >
Encoding:
Text File  |  1994-03-16  |  8.8 KB  |  384 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UGroupListCmds.cp
  3.  
  4. #include "UGroupListCmds.h"
  5. #include "UGroupListView.h"
  6. #include "UGroupList.h"
  7. #include "UGroupListDoc.h"
  8. #include "UGroupTree.h"
  9. #include "UNewsAppl.h"
  10. #include "UGroupDocCmds.h"
  11. #include "UNntp.h"
  12. #include "UProgress.h"
  13. #include "UPrefsDatabase.h"
  14. #include "UFatalError.h"
  15. #include "FileTools.h"
  16. #include "UThread.h"
  17.  
  18. #include <RsrcGlobals.h>
  19. #include <ErrorGlobals.h>
  20.  
  21. #include <Errors.h>
  22.  
  23. #pragma segment MyGroupList
  24.  
  25. #define qDebugListTypeName qDebug & 0
  26. #define qDebugNewArticlesCheck qDebug
  27.  
  28. //=========================================================================
  29. TUnsubscribeGroupTracker::TUnsubscribeGroupTracker()
  30. {
  31. }
  32.  
  33.  
  34. pascal void TUnsubscribeGroupTracker::Initialize()
  35. {
  36.     inherited::Initialize();
  37.     fGroupListView = nil;
  38. }
  39.  
  40. pascal void TUnsubscribeGroupTracker::IUnsubscribeGroupTracker(
  41.                                                 TGroupListView *groupListView,
  42.                                                 const VPoint &localMouse, Boolean makingCopy)
  43. {
  44. #if qDebug
  45.     if (!IsObject(groupListView))
  46.         ProgramBreak("groupListView is not object");
  47. #endif
  48.     groupListView->Focus();
  49.     CPoint globalMouse(localMouse.ToPoint());
  50.     LocalToGlobal(globalMouse);
  51.  
  52. #if qDebugGroupDrag
  53.     fprintf(stderr, "IUnsubscribeGroupTracker, localMouse = %s,", (char*)localMouse);
  54.     fprintf(stderr, "globalMouse = %s\n", (char*)globalMouse);
  55. #endif
  56.     IGroupTracker(cGroupListChange, globalMouse, makingCopy);
  57.     fGroupListView = groupListView;
  58.     
  59.     fMouseOffsetInGrayPict = localMouse.ToPoint();
  60. }
  61.  
  62. pascal void TUnsubscribeGroupTracker::Free()
  63. {
  64.     inherited::Free();
  65. }
  66.  
  67. void TUnsubscribeGroupTracker::GetBeforeGroupName(TGroupListView *groupListView, short beforeRow, CStr255 &name)
  68. {
  69.     if (groupListView == fGroupListView)
  70.     {
  71.         while (beforeRow <= fGroupListView->fNumOfRows && fGroupListView->IsCellSelected(GridCell(1, beforeRow)))
  72.             beforeRow++; // skip moved groups
  73.     }
  74.     inherited::GetBeforeGroupName(groupListView, beforeRow, name);
  75. }
  76.  
  77. void TUnsubscribeGroupTracker::MakeGrayPict()
  78. {
  79.     fGroupListView->Focus();    
  80.     ClipRect(CRect(0, 0, 1000, 1000));
  81.     fGrayPictH = OpenPicture(CRect(0, 0, 1000, 1000));
  82.     PenNormal();
  83.     PenPat(&qd.gray);
  84.     PenMode(patXor);
  85.  
  86.     CSelectedCellIterator iter(fGroupListView);
  87.     for (GridCell cell = iter.FirstCell(); iter.More(); cell = iter.NextCell())
  88.     {
  89.         CRect r;
  90.         fGroupListView->GetCellTextRect(cell, r);
  91.         FrameRect(r);
  92.     }
  93.     ClosePicture();
  94. }
  95.  
  96. void TUnsubscribeGroupTracker::CreateListOfDraggedGroups()
  97. {
  98.     fDraggedGroups = fGroupListView->GetSelectionAsList();
  99. }
  100.  
  101. void TUnsubscribeGroupTracker::CheckForExistingGroups(TGroupListView *hitGroupListView, Boolean makingCopy)
  102. {
  103.     if (hitGroupListView != fGroupListView)
  104.         inherited::CheckForExistingGroups(hitGroupListView, makingCopy);
  105.     if (fGroupListView && !makingCopy)
  106.         fGroupListView->DeleteSelection();
  107. }
  108. //=========================================================================
  109. TListTypeName::TListTypeName()
  110. {
  111. }
  112.  
  113.  
  114. pascal void TListTypeName::Initialize()
  115. {
  116.     inherited::Initialize();
  117.     fGroupList = nil;
  118.     fGroupListView = nil;
  119. }
  120.  
  121. void TListTypeName::IListTypeName(TGroupListView *glv, TToolboxEvent *event)
  122. {
  123.     inherited::IGroupViewTypeNameCommand(glv, event);
  124.     fGroupListView = glv;
  125.     fGroupList = fGroupListView->GetGroupList();
  126. #if qDebug
  127.     if (!IsObject(fGroupListView))
  128.         ProgramBreak("fGroupListView is not object");
  129.     if (!IsObject(fGroupList))
  130.         ProgramBreak("fGroupList is not object");
  131. #endif
  132. }
  133.  
  134. pascal void TListTypeName::Free()
  135. {
  136.     inherited::Free();
  137. }
  138.  
  139. void TListTypeName::GetLineText(ArrayIndex line, CStr255 &text)
  140. {
  141.     fGroupList->GetGroupAt(line, text);
  142. }
  143.  
  144. void TListTypeName::SetUp()
  145. {
  146.     fLastTick = fGroupListView->fLastTypeKeyTick;
  147.     fTypeChars = fGroupListView->fKeyTypeChars;
  148.     inherited::SetUp();
  149. }
  150.  
  151. void TListTypeName::SetDown()
  152. {
  153.     inherited::SetDown();
  154.     fGroupListView->fLastTypeKeyTick = fLastTick;
  155.     fGroupListView->fKeyTypeChars = fTypeChars;
  156. }
  157.  
  158. void TListTypeName::DoOneLine(ArrayIndex line)
  159. {
  160.     // split dot name out in parts, and call DoLine on each part
  161.     CStr255 text;
  162.     GetLineText(line, text);
  163. #if qDebugListTypeName
  164.     fprintf(stderr, "Got dot line: '%s'\n", (char*)text);
  165. #endif
  166.     while (true)
  167.     {
  168.         short pos = text.Pos(".");
  169.         if (!pos || pos > text.Length())
  170.             break;
  171.         CStr255 s(text.Copy(1, pos - 1));
  172.         if (s.Length())
  173.             DoLine(line, s);
  174. #if qDebugListTypeName
  175.         fprintf(stderr, "Examines '%s'\n", (char*)s);
  176. #endif
  177.         text.Delete(1, pos);
  178.     }
  179.     if (text.Length())
  180.         DoLine(line, text);
  181. #if qDebugListTypeName
  182.     fprintf(stderr, "Examines '%s'\n", (char*)text);
  183. #endif
  184. }
  185. //------------------------------------------------------
  186. TListTabKeyCommand::TListTabKeyCommand()
  187. {
  188. }
  189.  
  190. pascal void TListTabKeyCommand::Initialize()
  191. {
  192.     inherited::Initialize();
  193.     fGroupList = nil;
  194.     fGroupListView = nil;
  195. }
  196.  
  197. void TListTabKeyCommand::IListTabKeyCommand(TGroupListView *glv, Boolean forward)
  198. {
  199.     inherited::IGroupViewTabKeyCommand(glv, forward);
  200.     fGroupListView = glv;
  201.     fGroupList = fGroupListView->GetGroupList();
  202. #if qDebug
  203.     if (!IsObject(fGroupListView))
  204.         ProgramBreak("fGroupListView is not object");
  205.     if (!IsObject(fGroupList))
  206.         ProgramBreak("fGroupList is not object");
  207. #endif
  208. }
  209.  
  210. pascal void TListTabKeyCommand::Free()
  211. {
  212.     inherited::Free();
  213. }
  214.  
  215. void TListTabKeyCommand::GetLineText(ArrayIndex line, CStr255 &text)
  216. {
  217.     fGroupList->GetGroupAt(line, text);
  218. }
  219.  
  220. //=============================================================================
  221. TPeriodicCheckNewArticles::TPeriodicCheckNewArticles()
  222. {
  223. }
  224.  
  225. pascal void TPeriodicCheckNewArticles::Initialize()
  226. {
  227.     inherited::Initialize();
  228.     fGroupListDoc = nil;
  229.     fGroupList = nil;
  230.     fNntp = nil;
  231. }
  232.  
  233. void TPeriodicCheckNewArticles::IPeriodicCheckNewArticles(TGroupListDoc *doc)
  234. {
  235.     inherited::IPeriodicAction(true);
  236.     fGroupListDoc = doc;
  237.     fGroupList = fGroupListDoc->GetGroupList();
  238. }
  239.  
  240. pascal void TPeriodicCheckNewArticles::Free()
  241. {
  242.     GoSleep();
  243.     gNntpCache->ReturnNntp(fNntp); fNntp = nil;
  244.     fGroupListDoc = nil;
  245.     fGroupList = nil;
  246.     inherited::Free();
  247. }
  248.  
  249. void TPeriodicCheckNewArticles::DoPeriodic()
  250. {
  251.     InvalidateMenus();
  252.     FailSpaceIsLow();
  253.     if (!fGroupListDoc)
  254.     {
  255. #if qDebug
  256.         ProgramBreak("fGroupListDoc is nil");
  257. #endif
  258.         return;
  259.     }
  260.     FailInfo fi;
  261.     if (fi.Try())
  262.     {
  263.         DoTheCheck();
  264.         InvalidateMenus();
  265.         fi.Success();
  266.     }
  267.     else // fail
  268.     {
  269.         gNntpCache->DiscardNntp(fNntp); fNntp = nil;
  270.         gCurProgress->WorkDone();
  271.         InvalidateMenus();
  272.         fi.ReSignal();
  273.     }
  274. }
  275.  
  276. const char *TPeriodicCheckNewArticles::GetDebugDescription()
  277. {
  278.     return "TPeriodicCheckNewArticles";
  279. }
  280.     
  281. void TPeriodicCheckNewArticles::DoTheCheck()
  282. {
  283. // may not cache TGroupTree as it can be replaced when rebuilding/updating it
  284.     fNntp = gNntpCache->GetNntp();
  285.     for (ArrayIndex index = 1;index <= fGroupList->GetSize(); index++)
  286.     {
  287.         gCurThread->CheckYield();
  288.         CStr255 dotName;
  289.         fGroupList->GetGroupAt(index, dotName);
  290.         if (!gNewsAppl->GetGroupTree()->HasGroup(dotName))
  291.             continue;
  292.         FailSpaceIsLow();
  293.         long lastID;
  294.         if (!GetCurrentLastID(dotName, lastID))
  295.             continue;
  296.         if (lastID <= gNewsAppl->GetGroupTree()->GetLastReadArticleID(dotName))
  297.             fGroupListDoc->UpdateGroupStatus(dotName, false);
  298.         else
  299.             fGroupListDoc->UpdateGroupStatus(dotName, true);
  300.     }    
  301.     if (gPrefs->GetBooleanPrefs('AuUp'))
  302.         UpdateGroupDatabases();
  303.     gCurProgress->WorkDone();
  304.     gNntpCache->ReturnNntp(fNntp); fNntp = nil;
  305. }
  306.  
  307. void TPeriodicCheckNewArticles::UpdateGroupDatabases()
  308. {
  309.     for (ArrayIndex index = 1;index <= fGroupList->GetSize(); index++)
  310.     {
  311.         gCurThread->CheckYield();
  312.         CStr255 dotName;
  313.         fGroupList->GetGroupAt(index, dotName);
  314.         if (!gNewsAppl->GetGroupTree()->HasGroup(dotName))
  315.             continue;
  316.         long lastID;
  317.         if (!GetCurrentLastID(dotName, lastID))
  318.             continue;
  319.         FailSpaceIsLow();
  320.         FSSpec spec;
  321.         GoPublicFile(dotName, spec);
  322.         if (FileExist(spec) && lastID <= gNewsAppl->GetGroupTree()->GetLastUpdatedArticleID(dotName))
  323.             continue;
  324.         if (!UpdateGroup(dotName))
  325.             return;
  326.     }    
  327. }
  328.  
  329. Boolean TPeriodicCheckNewArticles::GetCurrentLastID(const CStr255 &dotName, long &lastID)
  330. {
  331.     FailInfo fi;
  332.     if (fi.Try())
  333.     {
  334.         fNntp->SetGroup(dotName, true);
  335.         gCurThread->CheckYield();
  336.         long firstID;
  337.         fNntp->GetGroupInfo(firstID, lastID);
  338.         if (lastID < firstID) // got no articles == no new articles
  339.             lastID = 0;
  340.         fi.Success();
  341.         return true;
  342.     }
  343.     else // fail
  344.     {
  345.         // don't blow this thread up, if we meet an unexisting group,
  346.         // just return "no new articles"
  347.         if (fi.error == errNntpBadGroup)
  348.             return false;
  349.         fi.ReSignal();
  350.     }
  351. }
  352.  
  353. Boolean TPeriodicCheckNewArticles::UpdateGroup(const CStr255 &dotName)
  354. {
  355.     TOpenGroupCommand *cmd = nil;
  356.     VOLATILE(cmd);
  357.     FailInfo fi;
  358.     if (fi.Try())
  359.     {
  360.         gCurProgress->SetStandardProgressType();
  361.         cmd = new TOpenGroupCommand();
  362.         cmd->IOpenGroupCommand(dotName, true, true, true);
  363.         cmd->DoIt();
  364.         cmd->Free(); cmd = nil;
  365.         fi.Success();
  366.         return true;
  367.     }
  368.     else // fail
  369.     {
  370.         FreeIfObject(cmd); cmd = nil;
  371.         switch (fi.error)
  372.         {
  373.             case noErr:
  374.                 return false;  // don't do anything, just try checking the next groups
  375.             
  376.             case memFullErr:
  377.                 return true; // don't do anything, just try checking the next groups
  378.             
  379.             default:
  380.                 fi.ReSignal();
  381.         }
  382.     }
  383. }
  384.