OOFILE  1.9
oofrepedit.cpp
Go to the documentation of this file.
1 // COPYRIGHT 1999 A.D. Software, All rights reserved
2 // oofrepedit.cpp
3 // report-writer layer of OOFILE database - editing classes
4 
5 #include "oofpch_r.h" // for precompilation of report files
6 
20 // default for debug builds
21 // to track interaction area coordinates and clicks
22 // #ifndef NDEBUG guards release builds for some people but also test OOF_DEBUG
23 // as it was too easy to have a release version creating interaction logs
24 #if !defined NDEBUG && defined OOF_DEBUG && !defined OOF_REPEDIT_LOG_FILENAME
25  #define OOF_REPEDIT_LOG_FILENAME "oofrep interaction.log"
26 #endif
27 
28 #ifndef H_OOFREPEDITX
29  #include "oofrepeditx.h"
30 #endif
31 
32 #ifdef OOF_MEM_DEBUG_LAST_INCLUDE
33  #include OOF_MEM_DEBUG_LAST_INCLUDE
34 #endif
35 
36 #ifndef OOF_NO_STDLIB
37  #ifndef std
38  using namespace std;
39  #endif
40 #endif
41 
42 
43 // -------------------------------------------------------
44 // o o f R e p D r a w a b l e
45 // -------------------------------------------------------
50 void
52 {
53  makeRender(*inEnv.parentGUIenv());
54  mRender = inEnv.editor()->makeDefaultRenderWrapper(mRender );
55 }
56 
57 
58 // -------------------------------------------------------
59 // o o f R e p E d i t i n g E n v i r o n m e n t
60 // -------------------------------------------------------
62  mEditor(theEditor),
63  mLastAreaOnPrevPage(0),
64  mInteractionPages(0)
65 {}
66 
67 
69 {
70  delete mInteractionPages;
71  assert(!mLastAreaOnPrevPage); // shouldn't be deleting editor halfway through split!
72 }
73 
74 
75 void
77 {
78  #ifdef OOF_REPEDIT_LOG_FILENAME
79  ofstream logStream(OOF_REPEDIT_LOG_FILENAME,ios::app);
80  logStream
81  << endl << endl << "oofRepEditingEnv::startEnvironment"
82 #ifdef _MSC_VER
83 // stupid VC5 bug with manipulator forces less efficient create temp
84  << '\t' << dbDateTime::currentTime() << endl
85 #else
86  << '\t' << dbDateTime::now << endl
87 #endif
88  << oofString('-', 60) << endl
89  ;
90  logStream.close();
91  #endif
92  delete mInteractionPages; // maybe drawing again after oofRepWindow::ReflowReport
93  mInteractionPages = new OOF_InteractionPages; // use pointer so deletable and can hide definition
95  assert(mInteractionPages->count()==1);
96  assert(!mLastAreaOnPrevPage); ;
97 
99 }
100 
101 
107 void
109 {
110  assert(!mLastAreaOnPrevPage); // shouldn't be ending draw halfway through split!
111 
113 }
114 
115 
116 
117 
121 void
123  short inX, short inY, short inCol, long inRow,
124  oofRepEditLink* inEditor, oofRepInteractorStrategy* inInteractor,
125  short inWidth, short inHeight
126 )
127 {
128  #ifdef OOF_REPEDIT_LOG_FILENAME
129  ofstream logStream(OOF_REPEDIT_LOG_FILENAME,ios::app);
130  logStream << "Adding Area (x,y,col,row,wid,ht,pagenumber): "
131  << inX << ", " << inY << ", "
132  << inCol << ", " << inRow << ", "
133  << inWidth << ", " << inHeight << ", "
134  << (mInteractionPages->count()-1) << endl;
135  logStream.close();
136  #endif
137 
138  if (!inInteractor)
139  inInteractor = editor()->defaultInteractor(); // which strategy may have been reset by subclass of oofRepEditor
141  inX, inY, inCol, inRow,
142  inEditor, inInteractor, inWidth, inHeight
143  );
144 }
145 
146 
147 void
149 {
150  #ifdef OOF_REPEDIT_LOG_FILENAME
151  ofstream logStream(OOF_REPEDIT_LOG_FILENAME,ios::app);
152  logStream << "Adding Area (x,y,col,row,pagenumber): " << inArea.X << ", " << inArea.Y << ", " << inArea.mCol << ", " << inArea.mRow <<", "<< (mInteractionPages->count()-1) << endl;
153  logStream.close();
154  #endif
156 }
157 
158 
159 void
160 oofRepEditingEnv::changeAreasToNewLink(long matchingRow, oofRepEditLink* matchingLink, oofRepEditLink* newLink)
161 {
162  assert(matchingLink!=newLink);
163  mInteractionPages->latestPage().changeAreasToNewLink(matchingRow, matchingLink, newLink);
164 }
165 
166 
167 void
169 {
170  const unsigned long yPos = oofRep::currentReport()->currentVerticalPos();
172 }
173 
174 
175 void
177 {
178  drawable->makeRender(*this);
179 }
180 
181 
182 void
184 {
185  drawable->makeRender(*this);
186 }
187 
188 
189 void
191 {
193  // update current page
195 }
196 
197 
202 void
204 {
205  assert(!mLastAreaOnPrevPage);
207  assert(splittingArea); // page can't be empty if we're splitting!
208  mLastAreaOnPrevPage = new OOF_InteractionArea( *splittingArea );
209  assert(mLastAreaOnPrevPage); // page can't be empty if we're splitting!
210 }
211 
212 
213 void
215 {
216  assert(mLastAreaOnPrevPage);
218  delete mLastAreaOnPrevPage;
219  mLastAreaOnPrevPage = 0;
220 }
221 
222 
223 void
224 oofRepEditingEnv::singleClick(short inX, short inY)
225 {
226  if (!mInteractionPages)
227  return; // in case click forwarded before finish setup - has happened in testing!
228 
229  const unsigned long currentPageNumber = previewPageOrdinal();
230  OOF_InteractionArea* theNearestArea = mInteractionPages->page(currentPageNumber).findAreaBelowAndRightOf(inX, inY);
231  #ifdef OOF_REPEDIT_LOG_FILENAME
232  ofstream logStream(OOF_REPEDIT_LOG_FILENAME,ios::app);
233  if (theNearestArea)
234  logStream
235  << "singleClick (x,y) @: " << inX << ", " << inY << " matching "
236  << theNearestArea->X << ", " << theNearestArea->Y << endl
237  ;
238  else
239  logStream << "singleClick (x,y, no match) @: " << inX << ", " << inY << endl;
240  logStream.close();
241  #endif
242 
243  if (theNearestArea) {
244  theNearestArea->singleClick(inX, inY, this);
245  }
246 }
247 
248 
249 // -------------------------------------------------------
250 // o o f R e p P i c t B l o c k
251 // -------------------------------------------------------
252 void
254 {
255  makeRender(*inEnv.parentGUIenv());
256  oofRepRender* wrappedRender = mRender;
257  mRender = inEnv.editor()->makeDefaultBlockRenderWrapper(wrappedRender);
258 }
259 
260 
261 // -------------------------------------------------------
262 // o o f R e p T e x t B l o c k
263 // -------------------------------------------------------
264 void
266 {
267  makeRender(*inEnv.parentGUIenv());
268  oofRepRender* wrappedRender = mRender;
269  mRender = inEnv.editor()->makeDefaultBlockRenderWrapper(wrappedRender);
270 }
271 
272 
273 // -------------------------------------------------------
274 // O O F _ I n t e r a c t i o n P a g e A r e a s
275 // -------------------------------------------------------
277  oofArray(sizeof(OOF_InteractionArea), 20, 60), // estimate likely need up to 20 (expand big chunks)
278  mAreas(0)
279 {
280  mUserStorage = (void**)&mAreas; // so parent can adjust ours as we expand
281 
282 }
283 
284 
286 {
287 // could do with check to see all deallocated
288  DeleteBits(false);
289  mBits = mAreas = 0; // avoid double-delete by zeroing mBits
290 
291  const unsigned long numOwnedLinks = mOwnedLinks.count();
292  for (unsigned long i=0; i<numOwnedLinks; i++) {
293  oofRepEditLink* theLink = (oofRepEditLink*) mOwnedLinks.value(i); // safe downcast
294  assert(theLink);
295  theLink->decRefs(); // may cause delete
296  }
297 }
298 
299 
300 void*
301 OOF_InteractionPageAreas::AllocBits(unsigned long numBits) const
302 {
303  OOF_InteractionArea* ret = new OOF_InteractionArea[numBits];
304  return ret;
305 }
306 
307 
308 void
309 OOF_InteractionPageAreas::DeleteBits(bool /* becauseExpanding */)
310 {
311 // we are supposed to know our own data pointer
312 // this gives us a chance to do a deep delete if !becauseExpanding
313  delete[] mAreas;
314 }
315 
316 
319 {
320  unsigned long lastMatch=0;
321  bool haveMatch = false;
322 
323 
324  const unsigned long numItems = count();
325  for (unsigned short i=0; i<numItems; i++) {
326  OOF_InteractionArea& theArea = mAreas[i];
327  if ( theArea.matchesPageLocation(inX, inY) ){
328  lastMatch = i;
329  haveMatch = true;
330  }
331 
332  }
333 
334  if(haveMatch){
335  OOF_InteractionArea& resultArea = mAreas[lastMatch];
336  return &resultArea;
337  }
338  else
339  return NULL;
340 }
341 
342 
346 void
347 OOF_InteractionPageAreas::addInteractionArea(short inX, short inY, short inCol, long inRow, oofRepEditLink* inEditor, oofRepInteractorStrategy* inInteractor, short inWidth, short inHeight)
348 {
349  assert(inEditor);
350 // assert(inHeight>0);
351  assert(inX>=0);
352  assert(inY>=0);
353  unsigned long allocSlot = AllocSlot();
354  OOF_InteractionArea& theArea = mAreas[allocSlot];
355  theArea.X = inX;
356  theArea.Y = inY;
357  theArea.mCol = inCol;
358  theArea.mRow = inRow;
359  theArea.mEditLink = inEditor;
360  theArea.mInteractionStrategy = inInteractor;
361  theArea.mWidth = inWidth;
362  theArea.mHeight = inHeight;
363 }
364 
365 
366 void
368 {
369  unsigned long allocSlot = AllocSlot();
370  OOF_InteractionArea& theArea = mAreas[allocSlot];
371  theArea = inArea;
372 }
373 
374 
375 
378 {
379  const unsigned long numItems = count();
380  if (numItems>0) {
381  OOF_InteractionArea& theArea = mAreas[numItems-1];
382  return &theArea;
383  }
384  else
385  return NULL;
386 }
387 
388 
394 void
396 {
397  assert(sizeof(unsigned long)==sizeof(oofRepEditLink*)); // yes I know this is a bit dodgy - guards
398  // indicating we'll have to change our array types on some 64 bit platforms!
399  const unsigned long asValue = (unsigned long) inLink;
400  mOwnedLinks.append(asValue);
401  inLink->incRefs(); // possibly share responsibility for triggering deletes
402 }
403 
404 
405 void
407 {
408  const unsigned long numItems = count();
409  for (unsigned short i=0; i<numItems; i++) {
410  OOF_InteractionArea& theArea = mAreas[i];
411  if ((theArea.Y==matchingRow) && (theArea.mEditLink==matchingLink) )
412  theArea.mEditLink = newLink;
413  }
414 }
415 
416 
427 void
429 {
430  const unsigned long numItems = count();
431  if (numItems==0)
432  return;
433 
434  const unsigned long lastItem = numItems-1;
435  if (mAreas[lastItem].mHeight>0)
436  return; // don't bother terminating row with fixed heights
437 
438  short lastY = mAreas[lastItem].Y;
439  assert(newY>=lastY);
440  short newHeight = newY - lastY;
441 
442  for (long i=lastItem; i>=0; i--) {
443  OOF_InteractionArea& theArea = mAreas[i];
444  if (theArea.Y!=lastY) { // finished a row, adjust figures
445  if (theArea.mHeight>0)
446  return; // terminate as soon as hit row with height
447  const short prevRowY = theArea.Y;
448  newHeight = lastY - prevRowY;
449  lastY = prevRowY;
450  }
451  theArea.mHeight = newHeight;
452  }
453 }
454 
455 // -------------------------------------------------------
456 // O O F _ I n t e r a c t i o n P a g e s
457 // -------------------------------------------------------
459  oofArray(sizeof(OOF_InteractionPageAreas), 10, 60), // estimate likely need up to 20 (expand big chunks)
460  mPages(0)
461 {
462  mUserStorage = (void**)&mPages; // so parent can adjust ours as we expand
463 }
464 
465 
467 {
468 // could do with check to see all deallocated
469  DeleteBits(false);
470  mBits = mPages = 0; // avoid double-delete by zeroing mBits
471 }
472 
473 
474 void*
475 OOF_InteractionPages::AllocBits(unsigned long numBits) const
476 {
478  return ret;
479 }
480 
481 
482 void
483 OOF_InteractionPages::DeleteBits(bool becauseExpanding)
484 {
485 // don't delete when expanding if our items are objects
486 // unless we've copied them somehow other than the default bitwise
487  if (!becauseExpanding)
488  delete[] mPages;
489 }
490 
491 
492 // -------------------------------------------------------
493 // O O F _ R e p B l o c k C e l l R o w
494 // -------------------------------------------------------
496  oofArray(sizeof(OOF_RepBlockCellMap), 3, 2),
497  mMaps(0)
498 {
499  mUserStorage = (void**)&mMaps; // so parent can adjust ours as we expand
500 }
501 
502 
504 {
505 // could do with check to see all deallocated
506  DeleteBits(false);
507  mBits = mMaps = 0; // avoid double-delete by zeroing mBits
508 }
509 
510 
511 void*
512 OOF_RepBlockCellRow::AllocBits(unsigned long numBits) const
513 {
514  OOF_RepBlockCellMap* ret = new OOF_RepBlockCellMap[numBits];
515  return ret;
516 }
517 
518 
519 void
520 OOF_RepBlockCellRow::DeleteBits(bool /* becauseExpanding */)
521 {
522 // we are supposed to know our own data pointer
523 // this gives us a chance to do a deep delete if !becauseExpanding
524  delete[] mMaps;
525 }
526 
527 
528 void
530 {
531  const unsigned int numCells = inBlock->countCells();
532  const unsigned long newMax = count() + numCells;
533  ExpandToInclude(newMax); // single-hit expansion instead of (typically) 3!
534  for (unsigned int i=0; i<numCells; i++)
535  AddMap(i, inBlock);
536 }
537 
538 
539 bool
540 OOF_RepBlockCellRow::findBlock(oofRepBlock* inBlock, short& outCol) const
541 {
542  const unsigned long numMaps = count();
543  for (unsigned long i=0; i<numMaps; i++) { // top-down search loop
544  if (mMaps[i].mBlock==inBlock) {
545  outCol = i;
546  return true;
547  }
548  }
549  return false;
550 }
551 
552 
553 void
554 OOF_RepBlockCellRow::AddMap(short inIndex, oofRepBlock* inBlock)
555 {
556  const unsigned long newIndex = AllocSlot();
557  mMaps[newIndex].mCellIndex = inIndex;
558  mMaps[newIndex].mBlock = inBlock;
559 }
560 
561 // -------------------------------------------------------
562 // O O F _ R e p B l o c k C e l l R o w s
563 // -------------------------------------------------------
565  oofArray(sizeof(OOF_RepBlockCellRow), 3, 2),
566  mRows(0)
567 {
568  mUserStorage = (void**)&mRows; // so parent can adjust ours as we expand
569 }
570 
571 
573 {
574 // could do with check to see all deallocated
575  DeleteBits(false);
576  mBits = mRows = 0; // avoid double-delete by zeroing mBits
577 }
578 
579 
580 void*
581 OOF_RepBlockCellRows::AllocBits(unsigned long numBits) const
582 {
583  OOF_RepBlockCellRow* ret = new OOF_RepBlockCellRow[numBits];
584  return ret;
585 }
586 
587 
588 void
589 OOF_RepBlockCellRows::DeleteBits(bool becauseExpanding)
590 {
591 // don't delete when expanding if our items are objects
592 // unless we've copied them somehow other than the default bitwise
593  if (!becauseExpanding)
594  delete[] mRows;
595 }
596 
597 
598 
599 
600 
601 
602 // -------------------------------------------------------
603 // O O F _ r e p E d it S e t u p V i s i t o r
604 // -------------------------------------------------------
615 public:
616  OOF_repEditSetupVisitor(bool settingBufferForever=true) :
617  OOF_repBufferSettingVisitor(settingBufferForever)
618  {};
619 
620 protected:
621  virtual void VisitIterableBandBody(oofRepBand*);
622 };
623 
624 
625 
640 void
642 {
643  dbView* inView = inBand->view();
644  if (!inView)
645  return;
646 
647  dbTable* viewTable = inView->table();
648  if (viewTable) {
651  else { // reset
652  if (viewTable->isRelatedClone())
654  else
656  }
657  }
658 // now iterate all fields in case any of them point to related tables
659 // which also require their save option changing
660  const unsigned int numFields = inView->count();
661  const dbTable::saveOptionsT newOption = mSettingBufferForever ?
663  dbTable::requireExplicitAndBuffer; // if not setting, assume all related
664 
665  OOF_mixColumnarBand* columnarInterface = inBand->asColumnarBand();
666  for (unsigned int col=0; col<numFields; col++) { // start field iteration (horizontal)
667  const dbField& theField = inView->field(col);
668  dbTable* fieldTable = theField.fieldTable();
669  if (fieldTable && fieldTable!=viewTable)
670  fieldTable->setSaveOption(newOption);
671 
672  // now evaluate if can edit
673  if (columnarInterface && theField.fieldIsVirtual() || theField.fieldIsJoinKey())
674  columnarInterface->setFieldNonEditable(col);
675 
676  } // loop all fields
677 }
678 
679 
680 // -------------------------------------------------------
681 // o o f R e p E d i t o r
682 // -------------------------------------------------------
684  mInteractionMappingActive(true),
685  mInteractsViaClicks(true),
686  mInteractsViaKeys(false),
687  mDefaultInteractor(new oofRepInteractorSimpleClickStrategy)
688 {
689 }
690 
691 
693 {
694  delete mDefaultInteractor;
695 }
696 
697 
700 {
701  return new oofRepEditor(*this);
702 }
703 
704 
705 // overrideable factories
708 {
709  return new oofRepEditingEnv(this);
710 }
711 
712 
713 
716 {
717  return new oofNonEditableRedirectingRender(adoptedRender);
718 }
719 
720 
723 {
724  return new oofRepBlockRedirectingRender(adoptedRender);
725 }
726 
727 
730 {
731  return new oofRepLayoutRedirectingRender(adoptedRender);
732 }
733 
734 
737 {
738  return new oofRepViewRedirectingRender(adoptedRender);
739 }
740 
741 
744 {
745  return new oofRepColHeaderEditLink(inViewBand);
746 }
747 
748 
751 {
752  return new oofRepLayoutEditLink(inLayoutBand);
753 }
754 
755 
757 oofRepEditor::makeViewEditLink(oofRepViewBand* inViewBand, bool editingSubSelection)
758 {
759  return new oofRepViewEditLink(inViewBand, editingSubSelection);
760 }
761 
762 
769 {
770  return new OOF_repEditSetupVisitor;
771 }
772 
773 
774 
775 // -------------------------------------------------------
776 // o o f R e p I n t e r a c t o r S i m p l e C l i c k S t r a t e g y
777 // -------------------------------------------------------
778 void
780 {
781  oofRepEditor* theEditor = inEnv->editor();
782  assert(theEditor);
783  if (theEditor->respondsToClicks()) {
784  theEditor->startEditing(inArea, inEnv);
785  }
786 }
787 
788 
789 
790 // -------------------------------------------------------
791 // o o f R e p E d i t L i n k
792 // -------------------------------------------------------
800  dbFieldLink(NULL, NULL),
801  OOF_mixRefCount(0), // don't have any refs until adopted
802  mDrawable(inD),
803  mCurrentCol(-1),
804  mLastRow(0),
805  mCurrentRow(-1),
806  mLastCol(0)
807 {
808 }
809 
810 
811 
813 {
814  mAdapter = 0; // we do NOT own it, unlike our parent dbFieldLink's expectation
815 }
816 
817 
818 // style access
819 
829 {
830  return mDrawable->textStyle();
831 }
832 
833 
836 {
837  return mDrawable->localTextStyle();
838 }
839 
840 
841 bool
843 {
844  return false;
845 }
846 
847 
848 // reflective methods to query link
849 bool
851 {
852  return false;
853 }
854 
855 
858 {
859  return NULL;
860 }
861 
862 
863 void
865 {
866  mAdapter = inAdapter;
867  inAdapter->setFieldLink(this);
868 }
869 
870 
871 bool
873 {
874  owner(NULL);
875  return true;
876 }
877 
878 
879 void
881 {
882 // empty virtual to hide parent
883 }
884 
885 
886 
887 // movement testing - default base assumes on first and only cell
888 
893 bool
895 {
896  return ((mCurrentCol==0) && (mCurrentRow==0));
897 }
898 
899 
903 bool
904 oofRepEditLink::getLastCoords(short& outCol, long& outRow) const
905 {
906  outCol = mLastCol;
907  outRow = mLastRow;
908  return ((mCurrentCol==mLastCol) && (mCurrentRow==mLastRow));
909 }
910 
911 
912 bool
913 oofRepEditLink::getLeftOfCurrent(short& outCol, long& outRow) const
914 {
915  if (mCurrentCol>0) {
916  outCol = mCurrentCol-1;
917  outRow = mCurrentRow;
918  return true;
919  }
920  else
921  return false;
922 }
923 
924 
925 bool
926 oofRepEditLink::getRightOfCurrent(short& outCol, long& outRow) const
927 {
928  return false;
929 }
930 
931 
932 bool
933 oofRepEditLink::getUpFromCurrent(short& outCol, long& outRow) const
934 {
935  return false;
936 }
937 
938 
939 bool
940 oofRepEditLink::getDownFromCurrent(short& outCol, long& outRow) const
941 {
942  return false;
943 }
944 
945 
946 
947 
948 // -------------------------------------------------------
949 // O O F _ m i x R e p A b s t r a c t C e l l E d i t o r
950 // -------------------------------------------------------
951 
953  dbHelper(0), // no major table
954  mAnyContentDirtied(false),
955  mEnv(0),
956  mCurrentLink(0),
957  mAdapter(0)
958 {}
959 
960 
962 {
963  delete mAdapter;
964 }
965 
966 
967 void
969 {
970  assert(!mEnv); // this is a construction step, not resetting model!
971  mEnv = inEnv; // may utterly ignore if can't move to other items
972  EnterLink(inLink); // point to it and load data
973 }
974 
975 
976 void
978 {
979  assert(!mCurrentLink);
980  assert(mAdapter); // test if user forgot InitEditControls in their subclass
981  mCurrentLink = inLink; // this is data link for the cells we're editing now!
982  inLink->enterLink(mAdapter);
983  inLink->owner(this); // init the dbFieldLink side to think we own it!
984 
985  LoadAndUpdate();
986 }
987 
988 
989 // optional behavioural overrides
997 void
999 {
1000 // override if want disabling etc.
1001 }
1002 
1003 
1009 void
1010 OOF_mixRepAbstractCellEditor::UnableToMoveWarning(movementT, bool /*movingByCell*/) // default beep
1011 {
1013 }
1014 
1015 
1016 
1017 // optional actions to override
1018 
1023 void
1025 {
1026  assert (mCurrentLink);
1027  oofString cellText = mCurrentLink->getCellText();
1028  cellText.lineEndingsCurrentPlatform(); // or could have application call dbText::convertsLineEndingsOnLoad(true)
1029  mAdapter->setString(cellText);
1030 }
1031 
1032 
1033 bool
1035 {
1036  assert (mCurrentLink);
1037  if (!mCurrentLink->isDirty()) // don't bother saving if not dirty
1038  return true;
1039 
1041  return true; // NOT YET IMPLEMENTED - failure returns
1042 }
1043 
1044 
1045 void
1047 {
1048  bool couldMove = false;
1049  short newCol;
1050  long newRow ;
1051 
1052  switch (inMove) {
1053  case (eGoFirst) :
1054  if (!mCurrentLink->atFirst()) {
1055  couldMove = true; // may still not move if Save cancels the attempt
1056  newCol = 0;
1057  newRow = 0;
1058  }
1059  break;
1060 
1061  case (eGoLast) : {
1062  couldMove = !mCurrentLink->getLastCoords(newCol, newRow);
1063  }
1064  break;
1065 
1066  case (eGoLeft) :
1067  couldMove = mCurrentLink->getLeftOfCurrent(newCol, newRow);
1068  break;
1069 
1070  case (eGoRight) :
1071  couldMove = mCurrentLink->getRightOfCurrent(newCol, newRow);
1072  break;
1073 
1074  case (eGoUp) :
1075  couldMove = mCurrentLink->getUpFromCurrent(newCol, newRow);
1076  break;
1077 
1078  case (eGoDown) :
1079  couldMove = mCurrentLink->getDownFromCurrent(newCol, newRow);
1080  break;
1081 
1082  default : {
1083  }
1084 
1085  }
1086 
1087  if (couldMove) {
1088  if (AttemptSaveCellEditField()) {
1089  mCurrentLink->setCurrentCoords(newCol, newRow);
1090  LoadAndUpdate();
1091  }
1092  }
1093  else
1094  UnableToMoveWarning(inMove, true);
1095 }
1096 
1097 
1102 void
1104 {
1105  assert(mCurrentLink);
1109 }
1110 
1111 
1117 void
1119 {
1120  UnableToMoveWarning(inMove, false); // warn because we don't know how to do it!
1121  return; // until we actually implement the find prev/next below
1122 // remove the above two lines when movement implemented below
1123 
1124  assert(mCurrentLink);
1125  oofRepEditLink* newLink = 0;
1126  switch (inMove) {
1127  case (eGoUp) :
1128  // NOT YET IMPLEMENTED - find prev item
1129  break;
1130 
1131  case (eGoDown) :
1132  // NOT YET IMPLEMENTED - find next item
1133  break;
1134 
1135  default :
1136  UnableToMoveWarning(inMove, false); // don't support most movement
1137  }
1138  if (newLink) {
1140  mCurrentLink = 0;
1141  EnterLink(newLink);
1142  }
1143 }
1144 
1145 
1146 void
1148 {
1149  mAnyContentDirtied = true; // latch dirtying of a cell so can test when save
1150 }
1151 
1152 
1153 
1154 // -------------------------------------------------------
1155 // o o f R e p L a y o u t E d i t L i n k
1156 // -------------------------------------------------------
1158  oofRepEditLink(inBand)
1159 {}
1160 
1161 
1162 // cell content access methods
1163 oofString
1164 oofRepLayoutEditLink::getCellText(bool* outIsEditable, oofString* outLocationName, long row, short col)
1165 {
1166  if (row==-1)
1167  row = mCurrentRow;
1168  if (col==-1)
1169  col = mCurrentCol;
1170 
1171  short cellInBlock;
1172  oofRepBlock* theBlock = MapCoordsToBlock(row, col, cellInBlock);
1173  assert(theBlock);
1174  // row/col for block is in terms of cells within block NOT within layout band
1175  bool isBlockEditable;
1176  const oofString ret = theBlock->getCellText(&isBlockEditable, outLocationName, 0, cellInBlock);
1177  if (outIsEditable)
1178  *outIsEditable = isBlockEditable;
1179  readOnly(!isBlockEditable);
1180  return ret;
1181 }
1182 
1183 
1184 void
1185 oofRepLayoutEditLink::setCellText(const oofString& inString, long row, short col)
1186 {
1187  if (row==-1)
1188  row = mCurrentRow;
1189  if (col==-1)
1190  col = mCurrentCol;
1191 
1192  short cellInBlock;
1193  oofRepBlock* theBlock = MapCoordsToBlock(row, col, cellInBlock);
1194  assert(theBlock);
1195  theBlock->setCellText(inString, 0, cellInBlock);
1196 }
1197 
1198 
1199 
1200 // reflective methods to query link
1201 bool
1203 {
1204  return true;
1205 }
1206 
1207 
1214 void
1216 {
1217 // leave mLastCol as 0 as we have to check row by row
1218 
1219  oofRepLayoutBand* theLayout = Drawable();
1220  const oofRepBlockList& theBlocks = theLayout->blocks();
1221  const unsigned long numBlocks = theLayout->blocks().count();
1222  assert(numBlocks>0); // guarantees at least one row
1223 
1224  // iterate all blocks, counting cells and putting into rows/cols
1225  bool nextBlockStartsRow = true;
1226  long numRows = 0;
1227  OOF_RepBlockCellRow* currentRow = 0;
1228  for (unsigned long i=0; i<numBlocks; i++) {
1229  if (nextBlockStartsRow) {
1230  currentRow = mRows.addRow();
1231  numRows++;
1232  }
1233 
1234  oofRepBlock* theBlock = theBlocks.value(i);
1235  assert(theBlock);
1236 
1237  currentRow->addBlockCells(theBlock);
1238  if (theBlock->moveDownAfter())
1239  nextBlockStartsRow = true;
1240  else
1241  nextBlockStartsRow = false;
1242  } // loop blocks
1243  mLastRow = numRows-1;
1244 }
1245 
1246 
1247 oofRepBlock*
1248 oofRepLayoutEditLink::MapCoordsToBlock(long inRow, short inCol, short& outCellInBlock) const
1249 {
1250  OOF_RepBlockCellRow& theRow = mRows.row(inRow);
1251  OOF_RepBlockCellMap& theMap = theRow.map(inCol);
1252  oofRepBlock* ret = theMap.mBlock;
1253  outCellInBlock = theMap.mCellIndex;
1254  return ret;
1255 }
1256 
1257 
1258 void
1259 oofRepLayoutEditLink::getFirstCoordsForBlock(oofRepBlock* inBlock, short& outCol, short& outRow) const
1260 {
1261  const unsigned long numRows = mRows.count();
1262  for (unsigned long i=0; i<numRows; i++) { // top-down search loop
1263  OOF_RepBlockCellRow& theRow = mRows.row(i);
1264  if (theRow.findBlock(inBlock, outCol)) { // first of many possible in a row
1265  outRow = i;
1266  return;
1267  }
1268  }
1269  outRow = outCol = -1;
1270 }
1271 
1272 
1273 bool
1274 oofRepLayoutEditLink::getRightOfCurrent(short& outCol, long& outRow) const
1275 {
1276  const long lastColInRow = mRows.row(mCurrentRow).count()-1;
1277  if (mCurrentCol<lastColInRow) {
1278  outCol = mCurrentCol+1;
1279  outRow = mCurrentRow;
1280  return true;
1281  }
1282  else
1283  return false;
1284 }
1285 
1286 
1287 bool
1288 oofRepLayoutEditLink::getUpFromCurrent(short& outCol, long& outRow) const
1289 {
1290  if (mCurrentRow>0) {
1291  const long newRow = mCurrentRow-1;
1292  const long lastColInRow = mRows.row(newRow).count()-1;
1293  if (lastColInRow<mCurrentCol)
1294  outCol = lastColInRow; // can't move up vertically but jump in a bit to last cell
1295  else
1296  outCol = mCurrentCol;
1297  outRow = newRow;
1298  return true;
1299  }
1300  else
1301  return false;
1302 }
1303 
1304 
1305 bool
1306 oofRepLayoutEditLink::getDownFromCurrent(short& outCol, long& outRow) const
1307 {
1308  if (mCurrentRow<mLastRow) {
1309  const long newRow = mCurrentRow+1;
1310  const long lastColInRow = mRows.row(newRow).count()-1;
1311  if (lastColInRow<mCurrentCol)
1312  outCol = lastColInRow; // can't move down vertically but jump in a bit to last cell
1313  else
1314  outCol = mCurrentCol;
1315  outRow = newRow;
1316  return true;
1317  }
1318  else
1319  return false;
1320 }
1321 
1322 
1323 // -------------------------------------------------------
1324 // o o f R e p V i e w E d i t L i n k
1325 // -------------------------------------------------------
1326 oofRepViewEditLink::oofRepViewEditLink(oofRepViewBand* inBand, bool editingSubSelection) :
1327  oofRepEditLink(inBand),
1328  mSelection(0),
1329  mRecordNumber(0)
1330 {
1331  dbView* theView = inBand->view();
1332  dbTable* viewTable = theView->table();
1333  mLastCol = theView->count() - 1;
1334  assert(mLastCol>=0); // check for empty view
1335 
1336  if (viewTable) {
1337  mLastRow = viewTable->count();
1338  if (mLastRow>0)
1339  --mLastRow; // valid to pass in empty selection so check before decrement
1340 
1341  if (editingSubSelection) {
1342  dbTable* tableToReset = viewTable->baseTableOfRelationChain();
1343  // tableToReset may be the same table as the view, if the sub selection
1344  // was on a unique table rather than a child related to the top view
1345  if (viewTable==tableToReset)
1346  mSelection = new dbSelection(tableToReset->currentSelection());
1347  else
1348  mRecordNumber = tableToReset->recordNumber();
1349  }
1350  }
1351  else
1352  mLastRow = 0;
1353 }
1354 
1355 
1357 {
1358  delete mSelection;
1359 }
1360 
1361 
1362 // init and cleanup code when edit dialog launches and if it changes links
1363 void
1365 {
1366  oofRepEditLink::enterLink(inAdapter);
1367  dbTable* viewTable = View()->table();
1368  if (viewTable) {
1369  dbTable* tableToReset = viewTable->baseTableOfRelationChain();
1370  if (mSelection)
1371  tableToReset->setSelection(*mSelection);
1372  else
1373  tableToReset->gotoRecord(mRecordNumber);
1374  } // has a table
1375 }
1376 
1377 
1378 // cell content access methods
1379 oofString
1380 oofRepViewEditLink::getCellText(bool* outIsEditable, oofString* outLocationName, long row, short col)
1381 {
1382  if (row==-1)
1383  row = mCurrentRow;
1384  if (col==-1)
1385  col = mCurrentCol;
1386 
1387  assert(row<=mLastRow && col<=mLastCol);
1388 
1389  dbTable* viewTable = View()->table();
1390  if (viewTable) {
1391  viewTable->gotoRecord(row);
1392  }
1393  else {
1394  assert(row==0); // only one row if no table
1395  }
1396 
1397 
1398  const dbField& theField = View()->field(col);
1399 
1400  const bool unableToEdit = Drawable()->fieldIsNonEditable(col);
1401  readOnly(unableToEdit);
1402  // NOT YET IMPLEMENTED allow for database locking - may fail if allowed updates
1403  // safe in these initial circumstances where all updates to database are buffered locally
1404  // due to bufferForever mode used on all report views
1405 
1406  if (outIsEditable)
1407  *outIsEditable = !unableToEdit;
1408 
1409  if (outLocationName) {
1410  const oofString theHeading = View()->getHeading(col);
1411  if (theHeading.isEmpty())
1412  outLocationName->convertNumber(col, "col %d");
1413  else
1414  *outLocationName = theHeading;
1415  outLocationName->convertNumber((unsigned long)row, " / %d", true /* append */);
1416  }
1417 
1418  return theField.copyString();
1419 }
1420 
1421 
1422 void
1423 oofRepViewEditLink::setCellText(const oofString& inString, long row, short col)
1424 {
1425  if (row==-1)
1426  row = mCurrentRow;
1427  if (col==-1)
1428  col = mCurrentCol;
1429 
1430  assert(row<=mLastRow && col<=mLastCol);
1431 
1432  dbTable* viewTable = View()->table();
1433  if (viewTable) {
1434  viewTable->gotoRecord(row);
1435  }
1436  else {
1437  assert(row==0); // only one row if no table
1438  }
1439 
1440  View()->writeableField(col)->setString(inString);
1441 }
1442 
1443 
1444 bool
1445 oofRepViewEditLink::getRightOfCurrent(short& outCol, long& outRow) const
1446 {
1447  if (mCurrentCol<mLastCol) {
1448  outCol = mCurrentCol+1;
1449  outRow = mCurrentRow;
1450  return true;
1451  }
1452  else
1453  return false;
1454 }
1455 
1456 
1457 bool
1458 oofRepViewEditLink::getUpFromCurrent(short& outCol, long& outRow) const
1459 {
1460  if (mCurrentRow>0) {
1461  outCol = mCurrentCol;
1462  outRow = mCurrentRow-1;
1463  return true;
1464  }
1465  else
1466  return false;
1467 }
1468 
1469 
1470 bool
1471 oofRepViewEditLink::getDownFromCurrent(short& outCol, long& outRow) const
1472 {
1473  if (mCurrentRow<mLastRow) {
1474  outCol = mCurrentCol;
1475  outRow = mCurrentRow+1;
1476  return true;
1477  }
1478  else
1479  return false;
1480 }
1481 
1482 
1483 bool
1485 {
1486  return false; // may change with adorners!
1487 }
1488 
1489 
1490 bool
1492 {
1493  return Drawable()->hasCustomViewDrawers();
1494 }
1495 
1496 
1499 {
1500  return Drawable()->customDrawer(col);
1501 }
1502 
1503 
1504 // -------------------------------------------------------
1505 // o o f R e p C o l H e a d e r E d i t L i n k
1506 // -------------------------------------------------------
1508  oofRepEditLink(inBand)
1509 {
1510  dbView* theView = inBand->view();
1511  mLastCol = theView->count() - 1;
1512 }
1513 
1514 
1515 bool
1516 oofRepColHeaderEditLink::getRightOfCurrent(short& outCol, long& outRow) const
1517 {
1518  if (mCurrentCol<mLastCol) {
1519  outCol = mCurrentCol+1;
1520  outRow = 0;
1521  return true;
1522  }
1523  else
1524  return false;
1525 }
1526 
1527 // cell content access methods
1528 oofString
1529 oofRepColHeaderEditLink::getCellText(bool* outIsEditable, oofString* outLocationName, long row, short col)
1530 {
1531  if (row==-1)
1532  row = 0;
1533  if (col==-1)
1534  col = mCurrentCol;
1535 
1536  assert(row<=mLastRow && col<=mLastCol);
1537 
1538  const bool canEdit = true;
1539  readOnly(!canEdit);
1540 
1541  if (outIsEditable)
1542  *outIsEditable = canEdit;
1543 
1544  if (outLocationName) {
1545  outLocationName->convertNumber(col, "Colum %d Heading");
1546  }
1547 
1548  return View()->getHeading(col);
1549 }
1550 
1551 
1556 void
1557 oofRepColHeaderEditLink::setCellText(const oofString& inString, long row, short col)
1558 {
1559  if (row==-1)
1560  row = 0;
1561  if (col==-1)
1562  col = mCurrentCol;
1563 
1564  assert(row<=mLastRow && col<=mLastCol);
1565 
1566  View()->setHeading(col, inString);
1568 }
1569 
1570 
1571 
1572 
1573 // -------------------------------------------------------
1574 // o o f R e p R e d i r e c t i n g R e n d e r
1575 // -------------------------------------------------------
1577  oofRepRenderDecorator(adoptedRender),
1578  mEditLink(0)
1579 {
1580 }
1581 
1582 
1584 {
1585 }
1586 
1587 
1588 bool
1590 {
1591  oofRep* curRep = oofRep::currentReport();
1592  oofRepEnvironment* theEnv = curRep->environment();
1593  if (theEnv->isPrintingEnvironment())
1594  return false;
1595 
1596  return true; // still rendering
1597 }
1598 
1599 
1600 // -------------------------------------------------------
1601 // o o f R e p L a y o u t R e d i r e c t i n g R e n d e r
1602 // -------------------------------------------------------
1603 oofRepLayoutRedirectingRender* oofRepLayoutRedirectingRender::sCurrentLayoutRedirectingRender;
1604 
1606  oofRepRedirectingRender(adoptedRender),
1607  mEditLink(0)
1608 {
1609 
1610 }
1611 
1612 
1621 {
1622  if(mEditLink)
1623  mEditLink->decRefs();
1624 }
1625 
1626 
1627 void
1629 {
1630  if (editRedirectionActive()) {
1631  sCurrentLayoutRedirectingRender = this;
1632  if (!mEditLink) // create for use by addAreaForCurrentBlock
1633  SetupEditLink();
1634 
1635  editingEnv()->pageAdoptsEditLink(mEditLink); // shares ownership with us
1636  }
1637 
1638  mWrappedRender->draw();
1639 
1640  if (editRedirectionActive())
1641  sCurrentLayoutRedirectingRender = 0;
1642 }
1643 
1644 
1645 void
1646 oofRepLayoutRedirectingRender::SetupEditLink()
1647 {
1648  oofRepLayoutBand* theLayout = LayoutRender()->ownerLayout();
1649  assert(!mEditLink);
1650  mEditLink = editor()->makeLayoutEditLink(theLayout);
1651  mEditLink->initMapping(); // link knows enough to go through and create map
1652  mEditLink->incRefs(); // extra link because we want it to stay around even if interaction areas deleted
1653 }
1654 
1655 
1656 oofRepRender*
1658 {
1659  oofRepLayoutBand_Render* clonedWrappee = (oofRepLayoutBand_Render*) mWrappedRender->clone(newOwner); // safe downcast
1660  return new oofRepLayoutRedirectingRender(clonedWrappee);
1661 }
1662 
1663 
1669 void
1671 {
1672  short xPos, yPos, col, row;
1673  oofRepBlock* theBlock;
1674  LayoutRender()->getCurrentBlockCoords(xPos, yPos, theBlock);
1675  mEditLink->getFirstCoordsForBlock(theBlock, col, row); // block may have several cells
1676  const unsigned long blockHeight = theBlock->fixedHeight();
1677  editingEnv()->addInteractionArea(xPos, yPos, col, row, mEditLink,
1678  NULL /* strategy */, 0, blockHeight
1679  );
1680  // could use theBlock->fixedWidth() but fails to take alignment into account
1681 }
1682 
1683 
1684 // -------------------------------------------------------
1685 // o o f R e p N o n E d i t a b l e R e d i r e c t i n g R e n d e r
1686 // -------------------------------------------------------
1688  oofRepRedirectingRender(adoptedRender)
1689 {
1690 }
1691 
1692 
1693 void
1695 {
1696  if (editRedirectionActive()) {
1698  }
1699 
1700 // after all that processing, forward the draw
1701  mWrappedRender->draw();
1702 }
1703 
1704 
1705 oofRepRender*
1707 {
1708  oofRepRender* clonedWrappee = mWrappedRender->clone(newOwner);
1709  return new oofNonEditableRedirectingRender(clonedWrappee);
1710 }
1711 
1712 
1713 
1714 
1715 // -------------------------------------------------------
1716 // o o f R e p B l o c k R e d i r e c t i n g R e n d e r
1717 // -------------------------------------------------------
1719  oofRepRedirectingRender(adoptedRender)
1720 {
1721 }
1722 
1723 
1724 void
1726 {
1727  if (editRedirectionActive()) {
1729  // layout does all the work - it knows location!
1730  }
1731 
1732 // after all that processing, forward the draw
1733  mWrappedRender->draw();
1734 }
1735 
1736 
1737 oofRepRender*
1739 {
1740  oofRepRender* clonedWrappee = mWrappedRender->clone(newOwner);
1741  return new oofRepBlockRedirectingRender(clonedWrappee);
1742 }
1743 
1744 
1745 
1746 
1747 // -------------------------------------------------------
1748 // o o f R e p V i e w R e d i r e c t i n g R e n d e r
1749 // -------------------------------------------------------
1751  oofRepRedirectingRender(adoptedRender),
1752  mColHeaderLink(0)
1753 {
1754 }
1755 
1756 
1758 {
1759  if(mColHeaderLink)
1761 }
1762 
1763 
1764 oofRepRender*
1766 {
1767  oofRepViewBand_Render* clonedWrappee = (oofRepViewBand_Render*) mWrappedRender->clone(newOwner); // safe downcast
1768  return new oofRepViewRedirectingRender(clonedWrappee);
1769 }
1770 
1771 
1778 void
1780 {
1781 // WARNING drawColumnHeaders() may well be called during the
1782 // wrapped draw() below
1783 
1784  if (editRedirectionActive()) {
1785  // record position before we do anything to manipulate
1787  }
1788 
1789 // after all that processing, forward the draw
1790  mWrappedRender->draw();
1791 }
1792 
1793 
1794 
1795 void
1797 {
1798  oofRep* curRep = oofRep::currentReport();
1799 
1800  dbView* theView = ViewBand()->view();
1801  assert(theView);
1802  oofColSizer* theSizer = theView->colSizer();
1803  const long numCols = theView->count();
1804  const short halfColSepWidth = curRep->settings()->colSepWidth() / 2;
1805 
1806  assert(mEditLink);
1807  const bool hasAdorners = (ViewBand()->adorners().count() > 0);
1808  short xPos = mWrappedRender->leftDrawMargin();
1809  const short yPos = curRep->currentVerticalPos();
1810  const long row = theView->recordNumber();
1811  for (unsigned short col=0; col<numCols; col++) {
1812  if (hasAdorners) // precompensate for gutter offset below
1813  xPos += halfColSepWidth;
1814  const long xPosInclGutter = xPos - halfColSepWidth;
1815  editingEnv()->addInteractionArea(xPosInclGutter, yPos, col, row, mEditLink);
1816  xPos += theSizer->width(col) + halfColSepWidth;
1817  }
1818 }
1819 
1820 
1823 {
1824  return (oofRepViewRedirectingRender*)newClone; // safe downcast
1825 }
1826 
1827 
1837 void
1839 {
1840  const bool editingHeaders = (editRedirectionActive() && mColHeaderLink);
1841  if (editingHeaders) {
1842  const short yPosBeforeHeaders = oofRep::currentReport()->currentVerticalPos();
1843  editingEnv()->changeAreasToNewLink(yPosBeforeHeaders, mEditLink, mColHeaderLink);
1844  }
1845 
1846  ((oofRepViewBand_Render*)mWrappedRender)->drawColumnHeaders(); // safe downcast because of ctor
1847 
1848  if (editingHeaders) {
1850  }
1851 }
1852 
1853 
1860 void
1862 {
1863  if (editRedirectionActive()) {
1864  oofRepViewBand* theViewBand = ViewBand();
1865  oofRep* curRep = oofRep::currentReport();
1866 
1867  const bool needsToCloneToSaveSubSelections = (curRep->nestedViewLevel()>oofRep::kBodyViewLevel);
1868  if (mEditLink) { // we are sub-table having called startTableBody before
1869  // don't delete old link, it's owned by someone else so we just cease to point at it
1870  // or we may be reflowing a report!
1871  }
1872 
1873  mEditLink = editor()->makeViewEditLink(theViewBand, needsToCloneToSaveSubSelections);
1874  editingEnv()->pageAdoptsEditLink(mEditLink); // this time is adopting it as link starts this page!
1875  if (!mColHeaderLink && curRep->shouldDrawViewColumnHeaders()) {
1876  mColHeaderLink = editor()->makeColHeaderEditLink(theViewBand);
1877  mColHeaderLink->incRefs(); // we want to hang onto it!
1878  }
1879  if (mColHeaderLink)
1880  editingEnv()->pageAdoptsEditLink(mColHeaderLink); // adopt the sole copy! - multiple refs
1881  // even if we already created it earlier, each new set of pages must share a ref
1882  }
1883 
1884  ((oofRepViewBand_Render*) mWrappedRender)->startTableBody(headersHaveChanged); // safe downcast
1885 }
1886 
1887 
1888 void
1890 {
1891 }
1892 
1893 
1894 
1895 // -------------------------------------------------------
1896 // r e n d e r f a c t o r i e s
1897 // -------------------------------------------------------
1898 void
1900 {
1901  makeRender(*inEnv.parentGUIenv());
1902  oofRepViewRedirectingRender* theRender = inEnv.editor()->makeViewRenderWrapper((oofRepViewBand_Render*)mRender); // safe downcast
1903  mRender = theRender;
1904  mTableExtraRender = theRender;
1905 // do NOT call mRender->finishConstruction();
1906 // as the wrapped render will have done its own finishConstruction in makeRender parent method
1907 }
1908 
1909 
1910 void
1912 {
1913  MakeAnyRender();
1914 }
1915 
1916 
1917 void
1919 {
1920  makeRender(*inEnv.parentGUIenv());
1921  mRender = inEnv.editor()->makeLayoutRenderWrapper((oofRepLayoutBand_Render*)mRender ); // safe downcast
1922 }
OOF_RepBlockCellRow & row(unsigned long) const
Definition: oofrepeditx.h:623
oofRepEditLink * mCurrentLink
Definition: oofrepedit.h:162
OOF_InteractionPages * mInteractionPages
owned
Definition: oofrepeditx.h:417
virtual void UnableToMoveWarning(movementT, bool movingByCell)
default beep
void colSizer(oofColSizer *adoptedSizer)
Definition: oofsize.cpp:71
virtual void draw()
per row
unsigned long count() const
Definition: oofarray.h:190
unsigned long previewPageOrdinal() const
returns ordinal number, NOT the printable page number which may reset
saveOptionsT
Definition: oof1.h:464
oofRepInteractorStrategy * defaultInteractor() const
Definition: oofrepeditor.h:101
oofRepEditor * editor() const
Definition: oofrepeditx.h:432
virtual void DeleteBits(bool becauseExpanding)
Definition: oofrepedit.cpp:589
virtual bool isPrintingEnvironment() const
Definition: oofrep2.cpp:1232
unsigned long count()
Count records in current selection.
Definition: oof1.h:2017
void LoadAndUpdate()
separation of these three steps, which commonly occurs, is example of the Template Method pattern all...
void ExpandToInclude(unsigned long indexToCover)
Definition: oofarray.cpp:380
virtual oofRepEditingEnv * makeEditingEnvironment()
Definition: oofrepedit.cpp:707
Abstract parent defining how report preview reacts to interaction.
Definition: oofrepedit.h:34
virtual unsigned long fixedHeight()
Definition: oofrep.h:2222
virtual ~oofRepEditor()
Definition: oofrepedit.cpp:692
virtual void LoadCellEditField()
Typical reasons to override - want to display location or a different display of the editable state (...
virtual oofRepRenderDecorator * makeDefaultBlockRenderWrapper(oofRepRender *adoptedRender)
Definition: oofrepedit.cpp:722
virtual void makeRender(const oofRepMacEnv &env)
Definition: oofrepMac.cpp:169
#define new
Definition: oofDebugNew.h:11
void ** mUserStorage
Definition: oofarray.h:103
unsigned long recordNumber() const
Ordinal record number of current record in selection.
Definition: oof1.h:2041
virtual dbView * view(unsigned short whichView=0) const
Request a dbView which may be the source of data for the item.
Definition: oofrep2.cpp:272
Abstract base for anything drawn on report.
Definition: oofrep.h:860
oofRepEditor * editor() const
Definition: oofrepeditx.h:458
oofRepBlock * mBlock
Definition: oofrepeditx.h:137
bool matchesPageLocation(short inX, short inY) const
Simple rectangular inclusion test.
Definition: oofrepeditx.h:581
OOF_RepBlockCellRow * mRows
Definition: oofrepeditx.h:179
Convenient mixin if your band is rendered in columns with custom drawing.
Definition: oofrep.h:980
OOF_InteractionArea * mAreas
typed reference to mBits
Definition: oofrepeditx.h:335
OOF_RepBlockCellMap & map(unsigned long) const
Definition: oofrepeditx.h:644
#define OOF_REPEDIT_LOG_FILENAME
Define to set filename for logging user interactions with report preview window.
Terminate previous areas so we know we have a dead area.
Definition: oofrepeditx.h:81
virtual oofRepRender * clone(const oofRepDrawable *newOwner) const
Decorator pattern - forwards most calls directly to owned renderer.
Definition: oofrep.h:834
oofRepEnvironment * environment() const
Definition: oofrep.h:1900
virtual void draw()
Definition: oofrep.h:821
Envelope class to contain an abstract selection apart from its dbTable.
Definition: oof1.h:316
virtual void setFieldLink(dbFieldLink *)
Definition: oofgui.cpp:864
oofRepCustomViewDrawer * customDrawer(unsigned short col)
Definition: oofrep2.cpp:172
void addBlockCells(oofRepBlock *)
Definition: oofrepedit.cpp:529
virtual void startEditing(OOF_InteractionArea *, oofRepEditingEnv *)
oofRepBlock * value(unsigned long) const
Definition: oofrep.h:2423
static std::ostream & now(std::ostream &os)
Definition: oof5.cpp:3766
virtual ~OOF_InteractionPageAreas()
Definition: oofrepedit.cpp:285
virtual ~OOF_RepBlockCellRows()
Definition: oofrepedit.cpp:572
virtual bool shouldDrawViewColumnHeaders() const
Definition: oofrep1.cpp:726
virtual bool AttemptSaveCellEditField()
virtual void singleClick(short x, short y)
interaction in progress
Definition: oofrepedit.cpp:224
virtual void endEnvironment()
virtual unsigned int countCells() const
Definition: oofrep1.cpp:1638
oofRepInteractorStrategy * mDefaultInteractor
Definition: oofrepeditor.h:72
virtual void DeleteBits(bool becauseExpanding)
Definition: oofrepedit.cpp:309
virtual oofRepEditLink * makeColHeaderEditLink(oofRepViewBand *)
Definition: oofrepedit.cpp:743
Record a block within an active oofRepLayoutRedirectingRender.
Definition: oofrepeditx.h:93
unsigned long count() const
Definition: oofarray.h:126
const dbField & field(unsigned int) const
Definition: oofview.h:206
unsigned long count() const
Definition: oofrep.h:2392
void AddMap(short inIndex, oofRepBlock *)
Definition: oofrepedit.cpp:554
Default redirector producing page map when render report to preview.
Definition: oofrepeditx.h:33
virtual oofRepRender * clone(const oofRepDrawable *newOwner) const =0
Most commonly used top band in a report.
Definition: oofrep.h:1283
oofRepEditLink * mColHeaderLink
owned, shared with OOF_InteractionPageAreas
Definition: oofrepeditx.h:126
oofRepEditingEnv(oofRepEditor *)
Definition: oofrepedit.cpp:61
oofAdornerList & adorners()
Definition: oofadorn.h:354
virtual void makeRender(const oofRepMacEnv &env)
Definition: oofrepMac.cpp:177
virtual void startTableBody(bool headersHaveChanged)
wrap entire process
Base rendering class.
Definition: oofrep.h:816
virtual void FinishCreationByLinkingDataModel(oofRepEditingEnv *, oofRepEditLink *)
Definition: oofrepedit.cpp:968
Mixin for reference counted classes which you want to auto-delete when their count falls to zero...
Definition: oof1.h:82
virtual void makeRenderDispatch(oofRepDrawable *) const
Definition: oofrepedit.cpp:176
virtual ~oofRepLayoutRedirectingRender()
Sometimes we will be deleted and page interaction areas still active, eg: if re-render a report from ...
virtual void resumeBandOverPage()
Definition: oofrepedit.cpp:214
virtual oofString getString() const =0
virtual OOF_mixViewExtraRender * finishClone(oofRepRender *newClone) const
Specify or calculate a set of column widths & alignments.
Definition: oofsize.h:51
Setup databases for editing.
Definition: oofrepedit.cpp:614
const oofRepSettings * settings() const
Definition: oofrep1.cpp:469
Subclass platform preview environment to intercept for editing hooks.
Definition: oofrepeditx.h:368
oofRepEditingEnv * mEnv
Definition: oofrepedit.h:161
virtual oofRepRenderDecorator * makeLayoutRenderWrapper(oofRepLayoutBand_Render *adoptedRender)
Definition: oofrepedit.cpp:729
virtual void * AllocBits(unsigned long) const
Definition: oofrepedit.cpp:581
OOF_RepBlockCellMap * mMaps
typed reference to mBits
Definition: oofrepeditx.h:159
Links a dbField to a known control type or I/O mechanism.
Definition: oofgui.h:74
oofRepInteractorStrategy * mInteractionStrategy
Definition: oofrepeditx.h:304
unsigned long width(unsigned short colNum)
Definition: oofsize.cpp:195
void pageAdoptsEditLink(oofRepEditLink *)
add edit link entry to page, which implies adoption of link if 1st time added to a page ...
Definition: oofrepeditx.h:439
void convertNumber(int, const char *printfMask=0, bool appendIt=false)
Definition: oofstr.cpp:882
unsigned long count() const
Definition: oofadorn.h:392
oofRepBlockList & blocks()
Definition: oofrep.h:2718
virtual oofRepRenderDecorator * makeDefaultRenderWrapper(oofRepRender *adoptedRender)
Definition: oofrepedit.cpp:715
Abstract base for rendering an oofRepLayoutBand.
Definition: oofreprn.h:57
virtual void DeleteBits(bool becauseExpanding)
Definition: oofrepedit.cpp:483
bool isRelatedClone() const
Definition: oof1.h:2348
Abstracts a drawing environment.
Definition: oofrep.h:406
Provide an iterable set of fields.
Definition: oofview.h:26
Redirector for layout objects, recording block positions.
Definition: oofrepeditx.h:55
virtual void setString(const oofString &)=0
unsigned long & currentVerticalPos()
Definition: oofrep.h:1941
virtual void maybeDirty(dbFieldLink *)
virtual void DeleteBits(bool becauseExpanding)
Definition: oofrepedit.cpp:520
virtual void setString(const char *)
Definition: oof3.h:132
virtual void singleClick(short inX, short inY, OOF_InteractionArea *, oofRepEditingEnv *)
Definition: oofrepedit.cpp:779
Setup databases for editing.
Definition: oofrep.h:1820
virtual void GoToAnotherItem(movementT)
Separate out item movement from cell movement because you may wish to implement one but use default f...
static void beep()
Definition: oof1.cpp:3362
OOF_repEditSetupVisitor(bool settingBufferForever=true)
Definition: oofrepedit.cpp:616
virtual oofRepViewRedirectingRender * makeViewRenderWrapper(oofRepViewBand_Render *adoptedRender)
Definition: oofrepedit.cpp:736
void startNonEditableArea()
Definition: oofrepedit.cpp:168
virtual oofRepRender * clone(const oofRepDrawable *newOwner) const
dbTable * baseTableOfRelationChain()
Definition: oof1.cpp:1984
Add extra virtual methods used by oofRep::DrawViewBand beyond normal band drawing.
Definition: oofreprn.h:111
virtual oofRepEditLink * makeViewEditLink(oofRepViewBand *, bool editingSubSelection)
Definition: oofrepedit.cpp:757
void dirtyColHeaders()
Definition: oofrep.h:2107
virtual oofRepVisitor * makeRepEditingSetupVisitor()
Overrideable factory for editsetup so you can invoke your own code.
Definition: oofrepedit.cpp:768
virtual void drawPageBreak()
unsigned long recordNumber() const
Definition: oofview.h:223
bool isEmpty() const
Test based on either length or null pointer.
Definition: oofstr.h:413
Top level class for a report.
Definition: oofrep.h:571
OOF_InteractionPageAreas & page(unsigned long index)
Definition: oofrepeditx.h:612
virtual void makeRender(const oofRepMacEnv &env)
Definition: oofrepMac.cpp:161
virtual void addInteractionArea(short inX, short inY, short inCol, long inRow, oofRepEditLink *inEditor, oofRepInteractorStrategy *inInteractor=0, short width=0, short height=0)
Add entry used in Flyweight pattern to react to clicks, etc.
Definition: oofrepedit.cpp:122
void addAreaForCurrentBlock() const
This is just a trigger callback from the wrapped layout render calling block renderers - our wrapped ...
oofRepLayoutRedirectingRender(oofRepLayoutBand_Render *adoptedRender=0)
virtual void setCellText(const oofString &, long row=0, short col=0)
Definition: oofrep1.cpp:1655
OOF_RepBlockCellRow * addRow()
Definition: oofrepeditx.h:631
Areas in just one page.
Definition: oofrepeditx.h:314
void setHeading(unsigned int, const char *)
Definition: oofview.cpp:308
virtual void drawPageBreak()
Definition: oofrepedit.cpp:190
bool moveDownAfter() const
Indicate if a layout band should start a new row of blocks.
Definition: oofrep.h:2215
void * mBits
Definition: oofarray.h:104
Describe single rectangular area within preview.
Definition: oofrepeditx.h:293
void EnterLink(oofRepEditLink *)
Definition: oofrepedit.cpp:977
static oofRepLayoutRedirectingRender * currentLayoutRedirectingRender()
Definition: oofrepeditx.h:529
dbSelection currentSelection()
Definition: oof1.cpp:2674
void setSelection(const dbSelection &)
Definition: oof1.cpp:2725
virtual void startEnvironment()
Definition: oofrepedit.cpp:76
Abstract base for user column drawer.
Definition: oofrep.h:1239
virtual void MakeAnyRender()
Definition: oofrep2.cpp:488
virtual void makeRender(const oofRepMacEnv &)
Definition: oofadorn.cpp:167
Map blocks within layout band back to an index for editing.
Definition: oofrepeditx.h:134
bool hasCustomViewDrawers() const
Definition: oofrep.h:2151
bool editRedirectionActive() const
visits all report objects.
Definition: oofrep.h:484
Abstract base for rendering an oofRepViewBand.
Definition: oofreprn.h:129
virtual oofString getCellText(bool *outIsEditable=0, oofString *outLocationName=0, long row=0, short col=0) const
Definition: oofrep1.cpp:1645
void addInteractionArea(short inX, short inY, short inCol, long inRow, oofRepEditLink *, oofRepInteractorStrategy *inInteractor=0, short inWidth=0, short inHeight=0)
Definition: oofrepedit.cpp:347
static dbDateTime currentTime()
Definition: oof5.cpp:3799
virtual void GoToAnotherCell(movementT)
virtual void VisitIterableBandBody(oofRepBand *)
Set databases associated with view to mode where editing is sensible.
Definition: oofrepedit.cpp:641
void changeAreasToNewLink(long matchingRow, oofRepEditLink *matchingLink, oofRepEditLink *newLink)
Definition: oofrepedit.cpp:160
OOF_InteractionPageAreas * mPages
typed reference to mBits
Definition: oofrepeditx.h:357
oofRepEditLink * mEditLink
just a ref - may be many maps to same editor!
Definition: oofrepeditx.h:303
virtual void * AllocBits(unsigned long) const
Definition: oofrepedit.cpp:475
virtual ~oofRepEditingEnv()
Definition: oofrepedit.cpp:68
virtual OOF_mixColumnarBand * asColumnarBand()
Definition: oofrep1.cpp:1568
bool gotoRecord(unsigned long)
Definition: oof1.cpp:2213
unsigned int count() const
Definition: oof1.h:1498
virtual void makeRender(const oofRepMacEnv &env)
Definition: oofrepMac.cpp:122
Base class for persistent tables.
Definition: oof1.h:452
dbTable * fieldTable() const
Definition: oof3.cpp:308
Portable highly capable string class.
Definition: oofstr.h:101
OOF_InteractionArea * mLastAreaOnPrevPage
Definition: oofrepeditx.h:416
virtual void startEnvironment()
oofRepRender * mWrappedRender
Definition: oofrep.h:851
void textStyle(oofRepTextStyle *adoptedStyle)
Set style owned by this object.
Definition: oofrep1.cpp:1804
bool lineEndingsCurrentPlatform()
Definition: oofstr.h:482
virtual void makeRender(const oofRepMacEnv &env)
Definition: oofrepMac.cpp:110
virtual void UpdateMovementButtons()
override to control disabling
Definition: oofrepedit.cpp:998
virtual void * AllocBits(unsigned long) const
Definition: oofrepedit.cpp:512
virtual void makeRender(const oofRepMacEnv &)
Definition: oofrep1.cpp:1334
oofRepEditor encapsulates the factories for all the roles in editing reports and provides a single po...
Definition: oofrepeditor.h:38
void setSaveOption(const saveOptionsT)
Definition: oof1.cpp:2752
void append(unsigned long)
Definition: oofarray.cpp:131
Specify a fixed-height band that contains a series of oofRepBlock's.
Definition: oofrep.h:1182
bool fieldIsNonEditable(unsigned short col) const
Definition: oofrep.h:2158
Abstract base for a fixed-size block drawn by an oofRepLayoutBand.
Definition: oofrep.h:1408
virtual ~OOF_RepBlockCellRow()
Definition: oofrepedit.cpp:503
Cross-platform specification of text style.
Definition: oofrep.h:732
Redirector for view band so maps whilst we page break.
Definition: oofrepeditx.h:108
void getCurrentBlockCoords(short &outX, short &outY, oofRepBlock *&outBlock) const
Definition: oofreprn.h:234
unsigned short colSepWidth() const
Definition: oofrep3.cpp:421
virtual bool fieldIsVirtual() const
Definition: oof3.cpp:400
oofNonEditableRedirectingRender(oofRepRender *adoptedRender=0)
oofRepRender * mRender
Definition: oofrep.h:901
OOF_InteractionArea * lastAreaAdded() const
may return NULL if none on page yet
Definition: oofrepedit.cpp:377
base class for user arrays.
Definition: oofarray.h:76
oofRepViewBand * ViewBand() const
Definition: oofrepeditx.h:518
Usual interactor triggering editing for a single click on the preview window.
Definition: oofrepeditx.h:282
bool fieldIsJoinKey() const
Checks if any relationships in field's table use field as join key.
Definition: oof3.cpp:327
virtual long leftDrawMargin() const
Definition: oofrep1.cpp:1431
virtual void drawColumnHeaders()
maybe do nothing but if drawn each page!
unsigned long AllocSlot()
Definition: oofarray.cpp:366
dbField * writeableField(unsigned int) const
Definition: oofview.h:214
bool findBlock(oofRepBlock *inBlock, short &outCol) const
Definition: oofrepedit.cpp:540
virtual dbView * view(unsigned short whichView=0) const
Request a dbView which may be the source of data for the item.
Definition: oofrep1.cpp:1253
virtual oofRepRender * clone(const oofRepDrawable *newOwner) const
void startNonEditableArea(unsigned long newY)
Sensible algorithm is only set those in the last row however earlier rows will then match due to thei...
Definition: oofrepedit.cpp:428
void singleClick(short inX, short inY, oofRepEditingEnv *)
Forward a click to our strategy.
Definition: oofrepeditx.h:571
Base object to derive adorners from.
Definition: oofadorn.h:32
OOF_ExpandableLongArray mOwnedLinks
secondary array of owned objects
Definition: oofrepeditx.h:336
virtual oofString copyString() const
Definition: oof3.cpp:472
bool respondsToClicks() const
Definition: oofrepeditor.h:80
parentGUIenvT * parentGUIenv() const
Definition: oofrepeditx.h:425
virtual oofRepEditor * clone() const
Definition: oofrepedit.cpp:699
Contain all the page maps for a preview window.
Definition: oofrepeditx.h:344
static oofRep * currentReport()
Definition: oofrep.h:2003
oofRepEditingEnv * editingEnv() const
Definition: oofrepeditx.h:449
oofRepEditLink * mEditLink
Definition: oofrepeditx.h:45
void decRefs()
Definition: oof1.cpp:3212
virtual ~OOF_InteractionPages()
Definition: oofrepedit.cpp:466
void incRefs()
Definition: oof1.h:2677
oofRepLayoutBand * ownerLayout() const
Definition: oofreprn.h:227
OOF_InteractionArea * findAreaBelowAndRightOf(short inX, short inY)
Definition: oofrepedit.cpp:318
virtual void * AllocBits(unsigned long) const
Definition: oofrepedit.cpp:301
List of blocks in an oofRepLayoutBand.
Definition: oofrep.h:336
oofRepBlockRedirectingRender(oofRepRender *adoptedRender=0)
Abstract base Controller class managing database to GUI mapping.
Definition: oofgui.h:355
virtual oofRepRender * clone(const oofRepDrawable *newOwner) const
OOF_InteractionPageAreas & latestPage()
return ref so less likely to hang onto expiring pointer
Definition: oofrepeditx.h:603
void setFieldNonEditable(unsigned short col)
Definition: oofrep2.cpp:191
oofRepViewRedirectingRender(oofRepViewBand_Render *adoptedRender=0)
void pageAdoptsEditLink(oofRepEditLink *)
add edit link entry to page, which implies adoption of link if 1st time added to a page ...
Definition: oofrepedit.cpp:395
virtual void endEnvironment()
we don't delete mAreas here but leave it active now that we've finished drawing the report it maps - ...
Definition: oofrepedit.cpp:108
dbTable * table() const
Definition: oofview.h:109
oofRepTextStyle * localTextStyle() const
Get style owned by this object.
Definition: oofrep.h:2654
virtual ~oofRepRedirectingRender()
Base class for persistent fields in dbTable's.
Definition: oof3.h:63
oofRepRedirectingRender(oofRepRender *adoptedRender=0)
virtual void splitBandOverPage()
Save a copy of the interaction area that we can use to create a new one at the top of the next page...
Definition: oofrepedit.cpp:203
Typed array of OOF_RepBlockCellMap with searches.
Definition: oofrepeditx.h:145
unsigned long value(unsigned long index) const
Definition: oofarray.cpp:243
Abstract base for report bands.
Definition: oofrep.h:1026
unsigned short nestedViewLevel() const
Definition: oofrep.h:2042
void changeAreasToNewLink(long matchingRow, oofRepEditLink *matchingLink, oofRepEditLink *newLink)
Definition: oofrepedit.cpp:406
virtual oofRepLayoutEditLink * makeLayoutEditLink(oofRepLayoutBand *)
Definition: oofrepedit.cpp:750
oofString getHeading(unsigned int, bool *tellIfOverride=0) const
Definition: oofview.cpp:278