Annotation of modules/damieng/graphical_editor/daxe/lib/src/toolbar.dart, revision 1.1
1.1 ! damieng 1: /*
! 2: This file is part of Daxe.
! 3:
! 4: Daxe is free software: you can redistribute it and/or modify
! 5: it under the terms of the GNU General Public License as published by
! 6: the Free Software Foundation, either version 3 of the License, or
! 7: (at your option) any later version.
! 8:
! 9: Daxe is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 12: GNU General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU General Public License
! 15: along with Daxe. If not, see <http://www.gnu.org/licenses/>.
! 16: */
! 17:
! 18: part of daxe;
! 19:
! 20: class Toolbar {
! 21: List<ToolbarItem> items;
! 22: List<x.Element> cacheRefs = null;
! 23: static final String iconPath = 'packages/daxe/images/toolbar/';
! 24:
! 25: Toolbar([Config cfg]) {
! 26: items = new List<ToolbarItem>();
! 27: if (doc.saveURL != null) {
! 28: ToolbarBox documentBox = new ToolbarBox();
! 29: documentBox.add(new ToolbarButton(Strings.get('menu.save'), iconPath + 'document_save.png',
! 30: () => page.save(), null));
! 31: items.add(documentBox);
! 32: }
! 33: ToolbarBox historyBox = new ToolbarBox();
! 34: historyBox.add(new ToolbarButton(Strings.get('undo.undo'), iconPath + 'history_undo.png',
! 35: () => doc.undo(), null, data:"undo", enabled:false));
! 36: historyBox.add(new ToolbarButton(Strings.get('undo.redo'), iconPath + 'history_redo.png',
! 37: () => doc.redo(), null, data:"redo", enabled:false));
! 38: items.add(historyBox);
! 39: ToolbarBox findBox = new ToolbarBox();
! 40: findBox.add(new ToolbarButton(Strings.get('find.find_replace'), iconPath + 'find.png',
! 41: () => (new FindDialog()).show(), null));
! 42: items.add(findBox);
! 43: if (cfg != null) {
! 44: // Buttons to insert new elements
! 45: ToolbarBox insertBox = new ToolbarBox();
! 46: List<x.Element> refs = cfg.elementsWithType('fichier');
! 47: if (refs != null && refs.length > 0) {
! 48: addInsertButton(cfg, insertBox, refs, iconPath + 'insert_image.png');
! 49: }
! 50: refs = cfg.elementsWithType('equationmem');
! 51: if (refs != null && refs.length > 0) {
! 52: addInsertButton(cfg, insertBox, refs, iconPath + 'equation.png');
! 53: }
! 54: refs = cfg.elementsWithType('symbole2');
! 55: if (refs != null && refs.length > 0) {
! 56: addInsertButton(cfg, insertBox, refs, iconPath + 'insert_symbol.png');
! 57: }
! 58: refs = cfg.elementsWithType('tabletexte');
! 59: if (refs != null && refs.length > 0) {
! 60: addInsertButton(cfg, insertBox, refs, iconPath + 'insert_table.png');
! 61: }
! 62: refs = cfg.elementsWithType('liste');
! 63: if (refs != null && refs.length > 0) {
! 64: addInsertButton(cfg, insertBox, refs, iconPath + 'ul.png');
! 65: }
! 66: items.add(insertBox);
! 67: // List buttons
! 68: List<x.Element> ulRefs = DNWList.ulRefs();
! 69: List<x.Element> olRefs = DNWList.olRefs();
! 70: if (ulRefs.length > 0 || olRefs.length > 0) {
! 71: ToolbarBox listBox = new ToolbarBox();
! 72: if (ulRefs.length > 0) {
! 73: ToolbarButton button = new ToolbarButton(_documentationFor(ulRefs[0]), iconPath + 'ul.png',
! 74: null, listButtonUpdate, data:new ToolbarStyleInfo(ulRefs, null, null));
! 75: button.action = () {
! 76: if (button.selected)
! 77: DNWList.riseLevel();
! 78: else
! 79: DNWList.addList((button.data as ToolbarStyleInfo).validRef);
! 80: };
! 81: listBox.add(button);
! 82: }
! 83: if (olRefs.length > 0) {
! 84: ToolbarButton button = new ToolbarButton(_documentationFor(olRefs[0]), iconPath + 'ol.png',
! 85: null, listButtonUpdate, data:new ToolbarStyleInfo(olRefs, null, null));
! 86: button.action = () {
! 87: if (button.selected)
! 88: DNWList.riseLevel();
! 89: else
! 90: DNWList.addList((button.data as ToolbarStyleInfo).validRef);
! 91: };
! 92: listBox.add(button);
! 93: }
! 94: listBox.add(new ToolbarButton(Strings.get('toolbar.rise_list_level'), iconPath + 'list_rise_level.png',
! 95: () => DNWList.riseLevel(), riseListLevelButtonUpdate, data:'rise_list_level'));
! 96: bool possibleListInItem = true; // will be true if it is always possible to have a list in an item of the same type
! 97: for (x.Element ulRef in ulRefs)
! 98: if (doc.cfg.findSubElement(DNWList.findItemRef(ulRef), ulRefs) == null)
! 99: possibleListInItem = false;
! 100: for (x.Element olRef in olRefs)
! 101: if (doc.cfg.findSubElement(DNWList.findItemRef(olRef), olRefs) == null)
! 102: possibleListInItem = false;
! 103: if (possibleListInItem)
! 104: listBox.add(new ToolbarButton(Strings.get('toolbar.lower_list_level'), iconPath + 'list_lower_level.png',
! 105: () => DNWList.lowerLevel(), lowerListLevelButtonUpdate, data:'lower_list_level'));
! 106: items.add(listBox);
! 107: }
! 108: // Link/Anchor buttons
! 109: List<x.Element> aRefs = DNAnchor.aRefs();
! 110: if (aRefs != null && aRefs.length > 0) {
! 111: ToolbarBox anchorBox = new ToolbarBox();
! 112: ToolbarButton button = new ToolbarButton(Strings.get('toolbar.insert_link'),
! 113: iconPath + 'add_link.png',
! 114: null, insertLinkButtonUpdate,
! 115: data:new ToolbarStyleInfo(aRefs, null, null));
! 116: button.action = () => DNAnchor.addLink((button.data as ToolbarStyleInfo).validRef);
! 117: anchorBox.add(button);
! 118: button = new ToolbarButton(Strings.get('toolbar.remove_link'),
! 119: iconPath + 'remove_link.png',
! 120: () => DNAnchor.removeLink(), removeLinkButtonUpdate,
! 121: data:new ToolbarStyleInfo(aRefs, null, null));
! 122: anchorBox.add(button);
! 123: button = new ToolbarButton(Strings.get('toolbar.insert_anchor'),
! 124: iconPath + 'anchor.png',
! 125: null, insertButtonUpdate,
! 126: data:new ToolbarStyleInfo(aRefs, null, null));
! 127: button.action = () => DNAnchor.addAnchor((button.data as ToolbarStyleInfo).validRef);
! 128: anchorBox.add(button);
! 129: items.add(anchorBox);
! 130: }
! 131: // Style buttons
! 132: ToolbarBox styleBox = new ToolbarBox();
! 133: List<x.Element> all = cfg.allElementsList();
! 134: for (x.Element ref in all) {
! 135: String dtype = cfg.elementDisplayType(ref);
! 136: if (dtype == 'style') {
! 137: String style = cfg.elementParameterValue(ref, 'style', null);
! 138: if (style == 'GRAS') {
! 139: addStyleButton(cfg, styleBox, ref, iconPath + 'style_bold.png', 'B');
! 140: } else if (style == 'ITALIQUE') {
! 141: addStyleButton(cfg, styleBox, ref, iconPath + 'style_italic.png', 'I');
! 142: } else if (style == 'EXPOSANT') {
! 143: addStyleButton(cfg, styleBox, ref, iconPath + 'style_superscript.png');
! 144: } else if (style == 'INDICE') {
! 145: addStyleButton(cfg, styleBox, ref, iconPath + 'style_subscript.png');
! 146: } else if (style == 'BARRE') {
! 147: addStyleButton(cfg, styleBox, ref, iconPath + 'style_strikethrough.png');
! 148: } else if (style == 'SOULIGNE') {
! 149: addStyleButton(cfg, styleBox, ref, iconPath + 'style_underline.png');
! 150: }
! 151: }
! 152: }
! 153: if (styleBox.length > 0) {
! 154: styleBox.add(new ToolbarButton(Strings.get('toolbar.remove_styles'), iconPath + 'remove_styles.png',
! 155: () => DNStyle.removeStylesFromSelection(), null, data:"remove_styles"));
! 156: items.add(styleBox);
! 157: }
! 158: if (doc.hiddenParaRefs != null) {
! 159: // Align buttons
! 160: String pStyleAtt = doc.cfg.elementParameterValue(doc.hiddenParaRefs[0], 'styleAtt', 'style');
! 161: // check if style attribute is allowed for hidden paragraphs
! 162: List<x.Element> attRefs = doc.cfg.elementAttributes(doc.hiddenParaRefs[0]);
! 163: bool found = false;
! 164: for (x.Element attRef in attRefs) {
! 165: if (doc.cfg.attributeName(attRef) == pStyleAtt) {
! 166: found = true;
! 167: break;
! 168: }
! 169: }
! 170: if (found) {
! 171: ToolbarBox alignBox = new ToolbarBox();
! 172: addParagraphCssButton(alignBox, 'text-align', 'left',
! 173: Strings.get('toolbar.align_left'), iconPath + 'align_left.png');
! 174: addParagraphCssButton(alignBox, 'text-align', 'right',
! 175: Strings.get('toolbar.align_right'), iconPath + 'align_right.png');
! 176: addParagraphCssButton(alignBox, 'text-align', 'center',
! 177: Strings.get('toolbar.align_center'), iconPath + 'align_center.png');
! 178: addParagraphCssButton(alignBox, 'text-align', 'justify',
! 179: Strings.get('toolbar.align_justify'), iconPath + 'align_justify.png');
! 180: items.add(alignBox);
! 181: }
! 182: }
! 183: x.Element spanRef = DNStyleSpan.styleSpanRef();
! 184: if (spanRef != null) {
! 185: // Font menu
! 186: List<String> fonts = ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'];
! 187: ToolbarMenu tbmenu = _makeStyleToolbarMenu(Strings.get('toolbar.font'), "font-family", fonts);
! 188: items.add(tbmenu);
! 189: /*
! 190: A size menu is a bad idea: larger font sizes are used for titles and it is
! 191: important to be able to extract titles automatically
! 192:
! 193: // Size menu
! 194: List<String> sizes = ['8', '9', '10', '11', '12', '14', '16', '18',
! 195: '20', '24', '28', '32', '36', '48', '72'];
! 196: tbmenu = _makeStyleToolbarMenu(Strings.get('toolbar.size'), "font-size", sizes, "px");
! 197: items.add(tbmenu);
! 198: */
! 199: }
! 200: }
! 201: }
! 202:
! 203: ToolbarMenu _makeStyleToolbarMenu(String title, String cssName, List<String> cssValues,
! 204: [String cssUnit]) {
! 205: Menu menu = new Menu(title);
! 206: menu.parent = this;
! 207: x.Element styleRef = DNStyleSpan.styleSpanRef();
! 208: for (String cssValue in cssValues) {
! 209: String cssValueWithUnit = cssValue;
! 210: if (cssUnit != null)
! 211: cssValueWithUnit += cssUnit;
! 212: MenuItem menuItem = new MenuItem(cssValue, null,
! 213: data:new ToolbarStyleInfo([styleRef], cssName, cssValueWithUnit));
! 214: menuItem.action = () {
! 215: if (menuItem.checked) {
! 216: Position start = page.getSelectionStart();
! 217: Position end = page.getSelectionEnd();
! 218: if (start == end && start.dn is DNText && start.dn.parent.ref == styleRef &&
! 219: (start.dn.parent as DNStyle).matchesCss(cssName, cssValueWithUnit) &&
! 220: start.dnOffset == start.dn.offsetLength && start.dn.nextSibling == null) {
! 221: // we are at the end of the style
! 222: // just move the cursor position outside of the style
! 223: DaxeNode styleNode = start.dn.parent;
! 224: page.moveCursorTo(new Position(styleNode.parent, styleNode.parent.offsetOf(styleNode)+1));
! 225: page.updateAfterPathChange();
! 226: } else
! 227: DNStyle.removeStylesFromSelection(styleRef, cssName);
! 228: } else {
! 229: DNStyle.removeAndApplyStyleToSelection(styleRef, cssName, cssValueWithUnit);
! 230: }
! 231: };
! 232: menu.add(menuItem);
! 233: }
! 234: ToolbarMenu tbmenu = new ToolbarMenu(menu, styleMenuUpdate, this);
! 235: return(tbmenu);
! 236: }
! 237:
! 238: add(ToolbarItem item) {
! 239: items.add(item);
! 240: }
! 241:
! 242: insert(ToolbarItem item, int position) {
! 243: items.insert(position, item);
! 244: }
! 245:
! 246: remove(int position) {
! 247: items.remove(position);
! 248: }
! 249:
! 250: List<ToolbarButton> get buttons {
! 251: List<ToolbarButton> buttons = new List<ToolbarButton>();
! 252: for (ToolbarItem item in items) {
! 253: if (item is ToolbarBox)
! 254: buttons.addAll(item.buttons);
! 255: }
! 256: return(buttons);
! 257: }
! 258:
! 259: /**
! 260: * Returns a list of all element references used in the toolbar.
! 261: */
! 262: List<x.Element> elementRefs() {
! 263: if (cacheRefs != null)
! 264: return(cacheRefs);
! 265: List<x.Element> list = new List<x.Element>();
! 266: for (ToolbarItem item in items) {
! 267: if (item is ToolbarBox) {
! 268: for (ToolbarButton button in item.buttons) {
! 269: if (button.data is ToolbarStyleInfo) {
! 270: ToolbarStyleInfo info = button.data;
! 271: if (info.possibleRefs != null)
! 272: list.addAll(info.possibleRefs);
! 273: }
! 274: }
! 275: } else if (item is ToolbarMenu) {
! 276: Menu menu = item.menu;
! 277: for (MenuItem menuItem in menu.items) {
! 278: if (menuItem.data is ToolbarStyleInfo) {
! 279: ToolbarStyleInfo info = menuItem.data;
! 280: if (info.possibleRefs != null)
! 281: list.addAll(info.possibleRefs);
! 282: }
! 283: }
! 284: }
! 285: }
! 286: cacheRefs = list;
! 287: return(list);
! 288: }
! 289:
! 290: h.Element html() {
! 291: h.DivElement div = new h.DivElement();
! 292: div.classes.add('toolbar');
! 293: for (ToolbarItem item in items) {
! 294: div.append(item.html());
! 295: }
! 296: return(div);
! 297: }
! 298:
! 299: String _documentationFor(x.Element ref) {
! 300: String documentation = doc.cfg.documentation(ref);
! 301: if (documentation == null)
! 302: documentation = doc.cfg.elementTitle(ref);
! 303: return(documentation);
! 304: }
! 305:
! 306: addInsertButton(Config cfg, ToolbarBox box, List<x.Element> refs, String icon) {
! 307: ToolbarButton button = new ToolbarButton(_documentationFor(refs[0]), icon,
! 308: null, insertButtonUpdate,
! 309: data:new ToolbarStyleInfo(refs, null, null));
! 310: button.action = () => doc.insertNewNode((button.data as ToolbarStyleInfo).validRef, 'element');
! 311: box.add(button);
! 312: }
! 313:
! 314: static void insertButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 315: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 316: // element insert
! 317: ToolbarStyleInfo info = button.data;
! 318: List<x.Element> refs = info.possibleRefs;
! 319: if (info.findValidRef(validRefs))
! 320: button.enable();
! 321: else
! 322: button.disable();
! 323: }
! 324:
! 325: addStyleButton(Config cfg, ToolbarBox box, x.Element ref, String icon, [String shortcut=null]) {
! 326: ToolbarButton button = new ToolbarButton(_documentationFor(ref), icon, null, dnStyleButtonUpdate,
! 327: data:new ToolbarStyleInfo([ref], null, null), shortcut:shortcut);
! 328: button.action = () {
! 329: if (button.selected) {
! 330: Position start = page.getSelectionStart();
! 331: Position end = page.getSelectionEnd();
! 332: if (start == end && start.dn is DNText && start.dn.parent.ref == ref &&
! 333: start.dnOffset == start.dn.offsetLength && start.dn.nextSibling == null) {
! 334: // we are at the end of the style
! 335: // just move the cursor position outside of the style
! 336: DaxeNode styleNode = start.dn.parent;
! 337: page.moveCursorTo(new Position(styleNode.parent, styleNode.parent.offsetOf(styleNode)+1));
! 338: page.updateAfterPathChange();
! 339: } else
! 340: DNStyle.removeStylesFromSelection(ref);
! 341: } else {
! 342: DNStyle.applyStyleInsideSelection(ref);
! 343: }
! 344: };
! 345: box.add(button);
! 346: }
! 347:
! 348: static void dnStyleButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 349: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 350: // DNStyle, style with no css (as with the b element)
! 351: ToolbarStyleInfo info = button.data;
! 352: List<x.Element> refs = info.possibleRefs;
! 353: bool foundAncestor = false;
! 354: for (x.Element possibleRef in refs) {
! 355: if (ancestorRefs.contains(possibleRef)) {
! 356: foundAncestor = true;
! 357: break;
! 358: }
! 359: }
! 360: if (foundAncestor) {
! 361: button.enable();
! 362: button.select();
! 363: } else {
! 364: if (selectedNode != null && refs.contains(selectedNode.ref))
! 365: button.select();
! 366: else
! 367: button.deselect();
! 368: if (info.findValidRef(validRefs))
! 369: button.enable();
! 370: else
! 371: button.disable();
! 372: }
! 373: }
! 374:
! 375: static void styleSpanButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 376: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 377: // DNSpanStyle, span style
! 378: ToolbarStyleInfo info = button.data;
! 379: x.Element ref = info.possibleRefs[0];
! 380: bool foundAncestor = false;
! 381: for (DaxeNode n = parent; n != null; n = n.parent) {
! 382: if (n.ref == ref && (n as DNStyleSpan).matchesCss(info.cssName, info.cssValue)) {
! 383: foundAncestor = true;
! 384: break;
! 385: }
! 386: }
! 387: if (foundAncestor) {
! 388: button.enable();
! 389: button.select();
! 390: } else {
! 391: if (selectedNode != null && ref == selectedNode.ref &&
! 392: (selectedNode as DNStyleSpan).matchesCss(info.cssName, info.cssValue)) {
! 393: button.select();
! 394: } else {
! 395: button.deselect();
! 396: }
! 397: if (validRefs.contains(ref))
! 398: button.enable();
! 399: else
! 400: button.disable();
! 401: }
! 402: }
! 403:
! 404: addParagraphCssButton(ToolbarBox alignBox, String cssName, String cssValue,
! 405: String title, String icon) {
! 406: ToolbarButton button = new ToolbarButton(title, icon,
! 407: null, paragraphButtonUpdate, data:new ToolbarStyleInfo(doc.hiddenParaRefs, cssName, cssValue));
! 408: button.action = () {
! 409: if (button.selected) {
! 410: DNHiddenP.removeStyleFromSelection(cssName);
! 411: } else {
! 412: DNHiddenP.applyStyleToSelection(cssName, cssValue);
! 413: }
! 414: };
! 415: alignBox.add(button);
! 416: }
! 417:
! 418: static void paragraphButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 419: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 420: ToolbarStyleInfo info = button.data;
! 421: bool foundAncestor = false;
! 422: for (DaxeNode n = parent; n != null; n = n.parent) {
! 423: if (doc.hiddenParaRefs.contains(n.ref)) {
! 424: if ((n as DNHiddenP).matchesCss(info.cssName, info.cssValue)) {
! 425: foundAncestor = true;
! 426: break;
! 427: }
! 428: }
! 429: }
! 430: if (foundAncestor) {
! 431: button.enable();
! 432: button.select();
! 433: } else {
! 434: if (selectedNode != null && doc.hiddenParaRefs.contains(selectedNode.ref) &&
! 435: (selectedNode as DNHiddenP).matchesCss(info.cssName, info.cssValue)) {
! 436: button.select();
! 437: } else {
! 438: button.deselect();
! 439: }
! 440: if (DNHiddenP.paragraphsInSelection().length > 0)
! 441: button.enable();
! 442: else
! 443: button.disable();
! 444: }
! 445: }
! 446:
! 447: static void listButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 448: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 449: // toggle list button
! 450: ToolbarStyleInfo info = button.data;
! 451: List<x.Element> refs = info.possibleRefs;
! 452: bool foundAncestor = false;
! 453: for (DaxeNode n = parent; n != null; n = n.parent) {
! 454: if (refs.contains(n.ref)) {
! 455: foundAncestor = true;
! 456: break;
! 457: }
! 458: }
! 459: if (foundAncestor) {
! 460: button.enable();
! 461: button.select();
! 462: } else {
! 463: button.deselect();
! 464: if (info.findValidRef(validRefs))
! 465: button.enable();
! 466: else
! 467: button.disable();
! 468: }
! 469: }
! 470:
! 471: static void riseListLevelButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 472: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 473: Position start = page.getSelectionStart();
! 474: DaxeNode dn = start.dn;
! 475: while (dn != null && dn is! DNWItem)
! 476: dn = dn.parent;
! 477: if (dn != null)
! 478: button.enable();
! 479: else
! 480: button.disable();
! 481: }
! 482:
! 483: static void lowerListLevelButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 484: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 485: Position start = page.getSelectionStart();
! 486: DaxeNode dn = start.dn;
! 487: while (dn != null && dn is! DNWItem)
! 488: dn = dn.parent;
! 489: if (dn == null || dn.previousSibling == null)
! 490: button.disable();
! 491: else
! 492: button.enable();
! 493: }
! 494:
! 495: static void insertLinkButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 496: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 497: ToolbarStyleInfo info = button.data;
! 498: if (page.getSelectionStart().dn is DNText && info.findValidRef(validRefs))
! 499: button.enable();
! 500: else
! 501: button.disable();
! 502: }
! 503:
! 504: static void removeLinkButtonUpdate(ToolbarButton button, DaxeNode parent, DaxeNode selectedNode,
! 505: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 506: ToolbarStyleInfo info = button.data;
! 507: List<x.Element> refs = info.possibleRefs;
! 508: bool foundAncestor = false;
! 509: for (x.Element possibleRef in refs) {
! 510: if (ancestorRefs.contains(possibleRef)) {
! 511: foundAncestor = true;
! 512: break;
! 513: }
! 514: }
! 515: if (foundAncestor)
! 516: button.enable();
! 517: else
! 518: button.disable();
! 519: }
! 520:
! 521: static void styleMenuUpdate(ToolbarMenu tbmenu, DaxeNode parent, DaxeNode selectedNode,
! 522: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 523: Menu menu = tbmenu.menu;
! 524: MenuItem selectedItem = null;
! 525: for (MenuItem menuItem in menu.items) {
! 526: if (menuItem.data is ToolbarStyleInfo) {
! 527: ToolbarStyleInfo info = menuItem.data;
! 528: x.Element ref = info.possibleRefs[0];
! 529: String cssName = info.cssName;
! 530: String cssValue = info.cssValue;
! 531: if (doc.hiddenParaRefs.contains(ref)) {
! 532: // paragraph style
! 533: bool foundAncestor = false;
! 534: for (DaxeNode n = parent; n != null; n = n.parent) {
! 535: if (doc.hiddenParaRefs.contains(n.ref) && (n as DNHiddenP).matchesCss(cssName, cssValue)) {
! 536: foundAncestor = true;
! 537: break;
! 538: }
! 539: }
! 540: if (foundAncestor) {
! 541: menuItem.enable();
! 542: selectedItem = menuItem;
! 543: menuItem.check();
! 544: } else {
! 545: if (selectedNode != null && doc.hiddenParaRefs.contains(selectedNode.ref) &&
! 546: (selectedNode as DNHiddenP).matchesCss(cssName, cssValue)) {
! 547: selectedItem = menuItem;
! 548: menuItem.check();
! 549: } else {
! 550: menuItem.uncheck();
! 551: }
! 552: if (DNHiddenP.paragraphsInSelection().length > 0)
! 553: menuItem.enable();
! 554: else
! 555: menuItem.disable();
! 556: }
! 557: } else if (doc.cfg.elementDisplayType(ref) == 'style') {
! 558: // DNStyle
! 559: if (ancestorRefs.contains(ref)) {
! 560: menuItem.enable();
! 561: selectedItem = menuItem;
! 562: } else {
! 563: if (selectedNode != null && ref == selectedNode.ref)
! 564: selectedItem = menuItem;
! 565: if (validRefs.contains(ref))
! 566: menuItem.enable();
! 567: else
! 568: menuItem.disable();
! 569: }
! 570: } else if (doc.cfg.elementDisplayType(ref) == 'stylespan') {
! 571: // DNSpanStyle
! 572: bool foundAncestor = false;
! 573: for (DaxeNode n = parent; n != null; n = n.parent) {
! 574: if (n.ref == ref && (n as DNStyleSpan).matchesCss(cssName, cssValue)) {
! 575: foundAncestor = true;
! 576: break;
! 577: }
! 578: }
! 579: if (foundAncestor) {
! 580: menuItem.enable();
! 581: selectedItem = menuItem;
! 582: menuItem.check();
! 583: } else {
! 584: if (selectedNode != null && ref == selectedNode.ref &&
! 585: (selectedNode as DNStyleSpan).matchesCss(cssName, cssValue)) {
! 586: selectedItem = menuItem;
! 587: menuItem.check();
! 588: } else {
! 589: menuItem.uncheck();
! 590: }
! 591: if (validRefs.contains(ref))
! 592: menuItem.enable();
! 593: else
! 594: menuItem.disable();
! 595: }
! 596: } else if (ref != null) {
! 597: // element insert
! 598: if (validRefs.contains(ref))
! 599: menuItem.enable();
! 600: else
! 601: menuItem.disable();
! 602: }
! 603: }
! 604: }
! 605: if (selectedItem == null)
! 606: menu.title = tbmenu.title;
! 607: else
! 608: menu.title = selectedItem.title;
! 609: }
! 610:
! 611: static void insertMenuUpdate(ToolbarMenu tbmenu, DaxeNode parent, DaxeNode selectedNode,
! 612: List<x.Element> validRefs, List<x.Element> ancestorRefs) {
! 613: Menu menu = tbmenu.menu;
! 614: for (MenuItem menuItem in menu.items) {
! 615: if (menuItem.data is ToolbarStyleInfo) {
! 616: ToolbarStyleInfo info = menuItem.data;
! 617: List<x.Element> refs = info.possibleRefs;
! 618: if (refs != null && refs.length > 0) {
! 619: // element insert
! 620: if (info.findValidRef(validRefs))
! 621: menuItem.enable();
! 622: else
! 623: menuItem.disable();
! 624: }
! 625: }
! 626: }
! 627: }
! 628:
! 629: void update(DaxeNode parent, List<x.Element> validRefs) {
! 630: List<x.Element> ancestorRefs = new List<x.Element>();
! 631: for (DaxeNode n = parent; n != null; n = n.parent)
! 632: ancestorRefs.add(n.ref);
! 633: DaxeNode selectedNode = null;// will be !=null when the selection matches a full element
! 634: Position start = page.getSelectionStart();
! 635: Position end = page.getSelectionEnd();
! 636: if (start.dn is! DNText && start.dn.offsetLength > start.dnOffset) {
! 637: if (end == new Position(start.dn, start.dnOffset + 1))
! 638: selectedNode = start.dn.childAtOffset(start.dnOffset);
! 639: }
! 640: // update buttons
! 641: for (ToolbarButton button in buttons) {
! 642: if (button.update != null)
! 643: button.update(button, parent, selectedNode, validRefs, ancestorRefs);
! 644: }
! 645: // update menus
! 646: for (ToolbarItem tbitem in items) {
! 647: if (tbitem is ToolbarMenu) {
! 648: tbitem.update(tbitem, parent, selectedNode, validRefs, ancestorRefs);
! 649: }
! 650: }
! 651: }
! 652:
! 653: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>