Changeset 27565
- Timestamp:
- 11/16/08 18:49:00 (2 months ago)
- Files:
-
- lyx-devel/trunk/src/Buffer.cpp (modified) (2 diffs)
- lyx-devel/trunk/src/Buffer.h (modified) (1 diff)
- lyx-devel/trunk/src/LyXFunc.cpp (modified) (3 diffs)
- lyx-devel/trunk/src/buffer_funcs.cpp (modified) (2 diffs)
- lyx-devel/trunk/src/buffer_funcs.h (modified) (1 diff)
- lyx-devel/trunk/src/insets/InsetTabular.cpp (modified) (1 diff)
- lyx-devel/trunk/src/insets/InsetText.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lyx-devel/trunk/src/Buffer.cpp
r27562 r27565 2685 2685 // do the real work 2686 2686 ParIterator parit = cbuf.par_iterator_begin(); 2687 lyx::updateLabels(*this,parit);2687 updateLabels(parit); 2688 2688 2689 2689 if (master != this) … … 2696 2696 } 2697 2697 2698 2699 static depth_type getDepth(DocIterator const & it) 2700 { 2701 depth_type depth = 0; 2702 for (size_t i = 0 ; i < it.depth() ; ++i) 2703 if (!it[i].inset().inMathed()) 2704 depth += it[i].paragraph().getDepth() + 1; 2705 // remove 1 since the outer inset does not count 2706 return depth - 1; 2707 } 2708 2709 static depth_type getItemDepth(ParIterator const & it) 2710 { 2711 Paragraph const & par = *it; 2712 LabelType const labeltype = par.layout().labeltype; 2713 2714 if (labeltype != LABEL_ENUMERATE && labeltype != LABEL_ITEMIZE) 2715 return 0; 2716 2717 // this will hold the lowest depth encountered up to now. 2718 depth_type min_depth = getDepth(it); 2719 ParIterator prev_it = it; 2720 while (true) { 2721 if (prev_it.pit()) 2722 --prev_it.top().pit(); 2723 else { 2724 // start of nested inset: go to outer par 2725 prev_it.pop_back(); 2726 if (prev_it.empty()) { 2727 // start of document: nothing to do 2728 return 0; 2729 } 2730 } 2731 2732 // We search for the first paragraph with same label 2733 // that is not more deeply nested. 2734 Paragraph & prev_par = *prev_it; 2735 depth_type const prev_depth = getDepth(prev_it); 2736 if (labeltype == prev_par.layout().labeltype) { 2737 if (prev_depth < min_depth) 2738 return prev_par.itemdepth + 1; 2739 if (prev_depth == min_depth) 2740 return prev_par.itemdepth; 2741 } 2742 min_depth = min(min_depth, prev_depth); 2743 // small optimization: if we are at depth 0, we won't 2744 // find anything else 2745 if (prev_depth == 0) 2746 return 0; 2747 } 2748 } 2749 2750 2751 static bool needEnumCounterReset(ParIterator const & it) 2752 { 2753 Paragraph const & par = *it; 2754 LASSERT(par.layout().labeltype == LABEL_ENUMERATE, /**/); 2755 depth_type const cur_depth = par.getDepth(); 2756 ParIterator prev_it = it; 2757 while (prev_it.pit()) { 2758 --prev_it.top().pit(); 2759 Paragraph const & prev_par = *prev_it; 2760 if (prev_par.getDepth() <= cur_depth) 2761 return prev_par.layout().labeltype != LABEL_ENUMERATE; 2762 } 2763 // start of nested inset: reset 2764 return true; 2765 } 2766 2767 2768 // set the label of a paragraph. This includes the counters. 2769 static void setLabel(Buffer const & buf, ParIterator & it) 2770 { 2771 BufferParams const & bp = buf.masterBuffer()->params(); 2772 DocumentClass const & textclass = bp.documentClass(); 2773 Paragraph & par = it.paragraph(); 2774 Layout const & layout = par.layout(); 2775 Counters & counters = textclass.counters(); 2776 2777 if (par.params().startOfAppendix()) { 2778 // FIXME: only the counter corresponding to toplevel 2779 // sectionning should be reset 2780 counters.reset(); 2781 counters.appendix(true); 2782 } 2783 par.params().appendix(counters.appendix()); 2784 2785 // Compute the item depth of the paragraph 2786 par.itemdepth = getItemDepth(it); 2787 2788 if (layout.margintype == MARGIN_MANUAL) { 2789 if (par.params().labelWidthString().empty()) 2790 par.params().labelWidthString(par.translateIfPossible(layout.labelstring(), bp)); 2791 } else { 2792 par.params().labelWidthString(docstring()); 2793 } 2794 2795 switch(layout.labeltype) { 2796 case LABEL_COUNTER: 2797 if (layout.toclevel <= bp.secnumdepth 2798 && (layout.latextype != LATEX_ENVIRONMENT 2799 || isFirstInSequence(it.pit(), it.plist()))) { 2800 counters.step(layout.counter); 2801 par.params().labelString( 2802 par.expandLabel(layout, bp)); 2803 } else 2804 par.params().labelString(docstring()); 2805 break; 2806 2807 case LABEL_ITEMIZE: { 2808 // At some point of time we should do something more 2809 // clever here, like: 2810 // par.params().labelString( 2811 // bp.user_defined_bullet(par.itemdepth).getText()); 2812 // for now, use a simple hardcoded label 2813 docstring itemlabel; 2814 switch (par.itemdepth) { 2815 case 0: 2816 itemlabel = char_type(0x2022); 2817 break; 2818 case 1: 2819 itemlabel = char_type(0x2013); 2820 break; 2821 case 2: 2822 itemlabel = char_type(0x2217); 2823 break; 2824 case 3: 2825 itemlabel = char_type(0x2219); // or 0x00b7 2826 break; 2827 } 2828 par.params().labelString(itemlabel); 2829 break; 2830 } 2831 2832 case LABEL_ENUMERATE: { 2833 // FIXME: Yes I know this is a really, really! bad solution 2834 // (Lgb) 2835 docstring enumcounter = from_ascii("enum"); 2836 2837 switch (par.itemdepth) { 2838 case 2: 2839 enumcounter += 'i'; 2840 case 1: 2841 enumcounter += 'i'; 2842 case 0: 2843 enumcounter += 'i'; 2844 break; 2845 case 3: 2846 enumcounter += "iv"; 2847 break; 2848 default: 2849 // not a valid enumdepth... 2850 break; 2851 } 2852 2853 // Maybe we have to reset the enumeration counter. 2854 if (needEnumCounterReset(it)) 2855 counters.reset(enumcounter); 2856 2857 counters.step(enumcounter); 2858 2859 string format; 2860 2861 switch (par.itemdepth) { 2862 case 0: 2863 format = N_("\\arabic{enumi}."); 2864 break; 2865 case 1: 2866 format = N_("(\\alph{enumii})"); 2867 break; 2868 case 2: 2869 format = N_("\\roman{enumiii}."); 2870 break; 2871 case 3: 2872 format = N_("\\Alph{enumiv}."); 2873 break; 2874 default: 2875 // not a valid enumdepth... 2876 break; 2877 } 2878 2879 par.params().labelString(counters.counterLabel( 2880 par.translateIfPossible(from_ascii(format), bp))); 2881 2882 break; 2883 } 2884 2885 case LABEL_SENSITIVE: { 2886 string const & type = counters.current_float(); 2887 docstring full_label; 2888 if (type.empty()) 2889 full_label = buf.B_("Senseless!!! "); 2890 else { 2891 docstring name = buf.B_(textclass.floats().getType(type).name()); 2892 if (counters.hasCounter(from_utf8(type))) { 2893 counters.step(from_utf8(type)); 2894 full_label = bformat(from_ascii("%1$s %2$s:"), 2895 name, 2896 counters.theCounter(from_utf8(type))); 2897 } else 2898 full_label = bformat(from_ascii("%1$s #:"), name); 2899 } 2900 par.params().labelString(full_label); 2901 break; 2902 } 2903 2904 case LABEL_NO_LABEL: 2905 par.params().labelString(docstring()); 2906 break; 2907 2908 case LABEL_MANUAL: 2909 case LABEL_TOP_ENVIRONMENT: 2910 case LABEL_CENTERED_TOP_ENVIRONMENT: 2911 case LABEL_STATIC: 2912 case LABEL_BIBLIO: 2913 par.params().labelString( 2914 par.translateIfPossible(layout.labelstring(), bp)); 2915 break; 2916 } 2917 } 2918 2919 2920 void Buffer::updateLabels(ParIterator & parit) const 2921 { 2922 LASSERT(parit.pit() == 0, /**/); 2923 2924 // set the position of the text in the buffer to be able 2925 // to resolve macros in it. This has nothing to do with 2926 // labels, but by putting it here we avoid implementing 2927 // a whole bunch of traversal routines just for this call. 2928 parit.text()->setMacrocontextPosition(parit); 2929 2930 depth_type maxdepth = 0; 2931 pit_type const lastpit = parit.lastpit(); 2932 for ( ; parit.pit() <= lastpit ; ++parit.pit()) { 2933 // reduce depth if necessary 2934 parit->params().depth(min(parit->params().depth(), maxdepth)); 2935 maxdepth = parit->getMaxDepthAfter(); 2936 2937 // set the counter for this paragraph 2938 setLabel(*this, parit); 2939 2940 // Now the insets 2941 InsetList::const_iterator iit = parit->insetList().begin(); 2942 InsetList::const_iterator end = parit->insetList().end(); 2943 for (; iit != end; ++iit) { 2944 parit.pos() = iit->pos; 2945 iit->inset->updateLabels(parit); 2946 } 2947 } 2948 } 2949 2698 2950 } // namespace lyx lyx-devel/trunk/src/Buffer.h
r27562 r27565 470 470 // the contents of the paragraphs. 471 471 void updateLabels(bool childonly = false) const; 472 /// 473 void updateLabels(ParIterator & parit) const; 472 474 473 475 private: lyx-devel/trunk/src/LyXFunc.cpp
r27562 r27565 1797 1797 1798 1798 1799 void LyXFunc::updateLayout(DocumentClass const * const oldlayout, Buffer * buf fer)1799 void LyXFunc::updateLayout(DocumentClass const * const oldlayout, Buffer * buf) 1800 1800 { 1801 1801 lyx_view_->message(_("Converting document to new document class...")); 1802 1802 1803 1803 StableDocIterator backcur(view()->cursor()); 1804 ErrorList & el = buf fer->errorList("Class Switch");1804 ErrorList & el = buf->errorList("Class Switch"); 1805 1805 cap::switchBetweenClasses( 1806 oldlayout, buf fer->params().documentClassPtr(),1807 static_cast<InsetText &>(buf fer->inset()), el);1808 1809 view()->setCursor(backcur.asDocIterator(&(buf fer->inset())));1810 1811 buf fer->errors("Class Switch");1812 buf fer->updateLabels();1806 oldlayout, buf->params().documentClassPtr(), 1807 static_cast<InsetText &>(buf->inset()), el); 1808 1809 view()->setCursor(backcur.asDocIterator(&(buf->inset()))); 1810 1811 buf->errors("Class Switch"); 1812 buf->updateLabels(); 1813 1813 } 1814 1814 … … 1828 1828 case LyXRC::RC_ALT_LANG: 1829 1829 case LyXRC::RC_PLAINTEXT_LINELEN: 1830 case LyXRC::RC_PLAINTEXT_ROFF_COMMAND: 1830 1831 case LyXRC::RC_AUTOREGIONDELETE: 1831 1832 case LyXRC::RC_AUTORESET_OPTIONS: … … 1970 1971 1971 1972 } // namespace anon 1972 1973 1974 1973 } // namespace lyx lyx-devel/trunk/src/buffer_funcs.cpp
r27562 r27565 88 88 } 89 89 Buffer * b = theBufferList().newBuffer(filename.absFilename()); 90 if (!b) 90 if (!b) { 91 91 // Buffer creation is not possible. 92 92 return 0; 93 } 93 94 if (!b->loadLyXFile(filename)) { 94 95 theBufferList().release(b); … … 217 218 } 218 219 219 220 namespace {221 222 depth_type getDepth(DocIterator const & it)223 {224 depth_type depth = 0;225 for (size_t i = 0 ; i < it.depth() ; ++i)226 if (!it[i].inset().inMathed())227 depth += it[i].paragraph().getDepth() + 1;228 // remove 1 since the outer inset does not count229 return depth - 1;230 }231 232 depth_type getItemDepth(ParIterator const & it)233 {234 Paragraph const & par = *it;235 LabelType const labeltype = par.layout().labeltype;236 237 if (labeltype != LABEL_ENUMERATE && labeltype != LABEL_ITEMIZE)238 return 0;239 240 // this will hold the lowest depth encountered up to now.241 depth_type min_depth = getDepth(it);242 ParIterator prev_it = it;243 while (true) {244 if (prev_it.pit())245 --prev_it.top().pit();246 else {247 // start of nested inset: go to outer par248 prev_it.pop_back();249 if (prev_it.empty()) {250 // start of document: nothing to do251 return 0;252 }253 }254 255 // We search for the first paragraph with same label256 // that is not more deeply nested.257 Paragraph & prev_par = *prev_it;258 depth_type const prev_depth = getDepth(prev_it);259 if (labeltype == prev_par.layout().labeltype) {260 if (prev_depth < min_depth)261 return prev_par.itemdepth + 1;262 if (prev_depth == min_depth)263 return prev_par.itemdepth;264 }265 min_depth = min(min_depth, prev_depth);266 // small optimization: if we are at depth 0, we won't267 // find anything else268 if (prev_depth == 0)269 return 0;270 }271 }272 273 274 bool needEnumCounterReset(ParIterator const & it)275 {276 Paragraph const & par = *it;277 LASSERT(par.layout().labeltype == LABEL_ENUMERATE, /**/);278 depth_type const cur_depth = par.getDepth();279 ParIterator prev_it = it;280 while (prev_it.pit()) {281 --prev_it.top().pit();282 Paragraph const & prev_par = *prev_it;283 if (prev_par.getDepth() <= cur_depth)284 return prev_par.layout().labeltype != LABEL_ENUMERATE;285 }286 // start of nested inset: reset287 return true;288 }289 290 291 // set the label of a paragraph. This includes the counters.292 void setLabel(Buffer const & buf, ParIterator & it)293 {294 BufferParams const & bp = buf.masterBuffer()->params();295 DocumentClass const & textclass = bp.documentClass();296 Paragraph & par = it.paragraph();297 Layout const & layout = par.layout();298 Counters & counters = textclass.counters();299 300 if (par.params().startOfAppendix()) {301 // FIXME: only the counter corresponding to toplevel302 // sectionning should be reset303 counters.reset();304 counters.appendix(true);305 }306 par.params().appendix(counters.appendix());307 308 // Compute the item depth of the paragraph309 par.itemdepth = getItemDepth(it);310 311 if (layout.margintype == MARGIN_MANUAL) {312 if (par.params().labelWidthString().empty())313 par.params().labelWidthString(par.translateIfPossible(layout.labelstring(), bp));314 } else {315 par.params().labelWidthString(docstring());316 }317 318 switch(layout.labeltype) {319 case LABEL_COUNTER:320 if (layout.toclevel <= bp.secnumdepth321 && (layout.latextype != LATEX_ENVIRONMENT322 || isFirstInSequence(it.pit(), it.plist()))) {323 counters.step(layout.counter);324 par.params().labelString(325 par.expandLabel(layout, bp));326 } else327 par.params().labelString(docstring());328 break;329 330 case LABEL_ITEMIZE: {331 // At some point of time we should do something more332 // clever here, like:333 // par.params().labelString(334 // bp.user_defined_bullet(par.itemdepth).getText());335 // for now, use a simple hardcoded label336 docstring itemlabel;337 switch (par.itemdepth) {338 case 0:339 itemlabel = char_type(0x2022);340 break;341 case 1:342 itemlabel = char_type(0x2013);343 break;344 case 2:345 itemlabel = char_type(0x2217);346 break;347 case 3:348 itemlabel = char_type(0x2219); // or 0x00b7349 break;350 }351 par.params().labelString(itemlabel);352 break;353 }354 355 case LABEL_ENUMERATE: {356 // FIXME: Yes I know this is a really, really! bad solution357 // (Lgb)358 docstring enumcounter = from_ascii("enum");359 360 switch (par.itemdepth) {361 case 2:362 enumcounter += 'i';363 case 1:364 enumcounter += 'i';365 case 0:366 enumcounter += 'i';367 break;368 case 3:369 enumcounter += "iv";370 break;371 default:372 // not a valid enumdepth...373 break;374 }375 376 // Maybe we have to reset the enumeration counter.377 if (needEnumCounterReset(it))378 counters.reset(enumcounter);379 380 counters.step(enumcounter);381 382 string format;383 384 switch (par.itemdepth) {385 case 0:386 format = N_("\\arabic{enumi}.");387 break;388 case 1:389 format = N_("(\\alph{enumii})");390 break;391 case 2:392 format = N_("\\roman{enumiii}.");393 break;394 case 3:395 format = N_("\\Alph{enumiv}.");396 break;397 default:398 // not a valid enumdepth...399 break;400 }401 402 par.params().labelString(counters.counterLabel(403 par.translateIfPossible(from_ascii(format), bp)));404 405 break;406 }407 408 case LABEL_SENSITIVE: {409 string const & type = counters.current_float();410 docstring full_label;411 if (type.empty())412 full_label = buf.B_("Senseless!!! ");413 else {414 docstring name = buf.B_(textclass.floats().getType(type).name());415 if (counters.hasCounter(from_utf8(type))) {416 counters.step(from_utf8(type));417 full_label = bformat(from_ascii("%1$s %2$s:"),418 name,419 counters.theCounter(from_utf8(type)));420 } else421 full_label = bformat(from_ascii("%1$s #:"), name);422 }423 par.params().labelString(full_label);424 break;425 }426 427 case LABEL_NO_LABEL:428 par.params().labelString(docstring());429 break;430 431 case LABEL_MANUAL:432 case LABEL_TOP_ENVIRONMENT:433 case LABEL_CENTERED_TOP_ENVIRONMENT:434 case LABEL_STATIC:435 case LABEL_BIBLIO:436 par.params().labelString(437 par.translateIfPossible(layout.labelstring(), bp));438 break;439 }440 }441 442 } // anon namespace443 444 void updateLabels(Buffer const & buf, ParIterator & parit)445 {446 LASSERT(parit.pit() == 0, /**/);447 448 // set the position of the text in the buffer to be able449 // to resolve macros in it. This has nothing to do with450 // labels, but by putting it here we avoid implementing451 // a whole bunch of traversal routines just for this call.452 parit.text()->setMacrocontextPosition(parit);453 454 depth_type maxdepth = 0;455 pit_type const lastpit = parit.lastpit();456 for ( ; parit.pit() <= lastpit ; ++parit.pit()) {457 // reduce depth if necessary458 parit->params().depth(min(parit->params().depth(), maxdepth));459 maxdepth = parit->getMaxDepthAfter();460 461 // set the counter for this paragraph462 setLabel(buf, parit);463 464 // Now the insets465 InsetList::const_iterator iit = parit->insetList().begin();466 InsetList::const_iterator end = parit->insetList().end();467 for (; iit != end; ++iit) {468 parit.pos() = iit->pos;469 iit->inset->updateLabels(parit);470 }471 }472 }473 474 220 } // namespace lyx lyx-devel/trunk/src/buffer_funcs.h
r27562 r27565 48 48 int countChars(DocIterator const & from, DocIterator const & to, bool with_blanks); 49 49 50 ///51 void updateLabels(Buffer const &, ParIterator &);52 53 50 } // namespace lyx 54 51 lyx-devel/trunk/src/insets/InsetTabular.cpp
r27481 r27565 3221 3221 size_t const end = it2.nargs(); 3222 3222 for ( ; it2.idx() < end; it2.top().forwardIdx()) 3223 lyx::updateLabels(buffer(),it2);3223 buffer().updateLabels(it2); 3224 3224 3225 3225 //reset afterwards lyx-devel/trunk/src/insets/InsetText.cpp
r27481 r27565 459 459 ParIterator it2 = it; 460 460 it2.forwardPos(); 461 LASSERT(&it2.inset() == this && it2.pit() == 0, /**/);462 if (producesOutput()) 463 lyx::updateLabels(buffer(),it2);464 else {461 LASSERT(&it2.inset() == this && it2.pit() == 0, return); 462 if (producesOutput()) { 463 buffer().updateLabels(it2); 464 } else { 465 465 DocumentClass const & tclass = buffer().masterBuffer()->params().documentClass(); 466 466 Counters const savecnt = tclass.counters(); 467 lyx::updateLabels(buffer(),it2);467 buffer().updateLabels(it2); 468 468 tclass.counters() = savecnt; 469 469 }
