1 /* 2 * Copyright 2006, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "MoveStylesCommand.h" 10 11 #include <new> 12 #include <stdio.h> 13 14 #include "StyleContainer.h" 15 #include "Style.h" 16 17 using std::nothrow; 18 19 // constructor 20 MoveStylesCommand::MoveStylesCommand(StyleContainer* container, 21 Style** styles, 22 int32 count, 23 int32 toIndex) 24 : Command(), 25 fContainer(container), 26 fStyles(styles), 27 fIndices(count > 0 ? new (nothrow) int32[count] : NULL), 28 fToIndex(toIndex), 29 fCount(count) 30 { 31 if (!fContainer || !fStyles || !fIndices) 32 return; 33 34 // init original style indices and 35 // adjust toIndex compensating for items that 36 // are removed before that index 37 int32 itemsBeforeIndex = 0; 38 for (int32 i = 0; i < fCount; i++) { 39 fIndices[i] = fContainer->IndexOf(fStyles[i]); 40 if (fIndices[i] >= 0 && fIndices[i] < fToIndex) 41 itemsBeforeIndex++; 42 } 43 fToIndex -= itemsBeforeIndex; 44 } 45 46 // destructor 47 MoveStylesCommand::~MoveStylesCommand() 48 { 49 delete[] fStyles; 50 delete[] fIndices; 51 } 52 53 // InitCheck 54 status_t 55 MoveStylesCommand::InitCheck() 56 { 57 if (!fContainer || !fStyles || !fIndices) 58 return B_NO_INIT; 59 60 // analyse the move, don't return B_OK in case 61 // the container state does not change... 62 63 int32 index = fIndices[0]; 64 // NOTE: fIndices == NULL if fCount < 1 65 66 if (index != fToIndex) { 67 // a change is guaranteed 68 return B_OK; 69 } 70 71 // the insertion index is the same as the index of the first 72 // moved item, a change only occures if the indices of the 73 // moved items is not contiguous 74 bool isContiguous = true; 75 for (int32 i = 1; i < fCount; i++) { 76 if (fIndices[i] != index + 1) { 77 isContiguous = false; 78 break; 79 } 80 index = fIndices[i]; 81 } 82 if (isContiguous) { 83 // the container state will not change because of the move 84 return B_ERROR; 85 } 86 87 return B_OK; 88 } 89 90 // Perform 91 status_t 92 MoveStylesCommand::Perform() 93 { 94 status_t ret = B_OK; 95 96 // remove styles from container 97 for (int32 i = 0; i < fCount; i++) { 98 if (fStyles[i] && !fContainer->RemoveStyle(fStyles[i])) { 99 ret = B_ERROR; 100 break; 101 } 102 } 103 if (ret < B_OK) 104 return ret; 105 106 // add styles to container at the insertion index 107 int32 index = fToIndex; 108 for (int32 i = 0; i < fCount; i++) { 109 if (fStyles[i] && !fContainer->AddStyle(fStyles[i], index++)) { 110 ret = B_ERROR; 111 break; 112 } 113 } 114 115 return ret; 116 } 117 118 // Undo 119 status_t 120 MoveStylesCommand::Undo() 121 { 122 status_t ret = B_OK; 123 124 // remove styles from container 125 for (int32 i = 0; i < fCount; i++) { 126 if (fStyles[i] && !fContainer->RemoveStyle(fStyles[i])) { 127 ret = B_ERROR; 128 break; 129 } 130 } 131 if (ret < B_OK) 132 return ret; 133 134 // add styles to container at remembered indices 135 for (int32 i = 0; i < fCount; i++) { 136 if (fStyles[i] && !fContainer->AddStyle(fStyles[i], fIndices[i])) { 137 ret = B_ERROR; 138 break; 139 } 140 } 141 142 return ret; 143 } 144 145 // GetName 146 void 147 MoveStylesCommand::GetName(BString& name) 148 { 149 if (fCount > 1) 150 name << "Move Styles"; 151 else 152 name << "Move Style"; 153 } 154