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