Beispiel #1
0
        /// <summary>
        /// Validates given row and updates its error messages
        /// </summary>
        protected override void Validate(DataGridViewKeyValueRow <CodeStringResultItem> row)
        {
            object dest            = row.Cells[DestinationColumnName].Value;
            bool   existsSameValue = false;

            if (dest == null)   // no destination file was selected
            {
                row.ErrorMessages.Add(NoDestinationFileError);
            }
            else
            {
                row.ErrorMessages.Remove(NoDestinationFileError);

                ResXProjectItem resxItem = resxItemsCache[dest.ToString()];
                if (!resxItem.IsLoaded)
                {
                    resxItem.Load();                                                                          // load the ResX file
                    VLDocumentViewsManager.SetFileReadonly(resxItem.InternalProjectItem.GetFullPath(), true); // lock it
                    loadedItems.Add(resxItem);
                }

                string key   = row.Key;
                string value = row.Value;

                CONTAINS_KEY_RESULT keyConflict = resxItem.GetKeyConflictType(key, value, true); // get conflict type
                switch (keyConflict)
                {
                case CONTAINS_KEY_RESULT.EXISTS_WITH_SAME_VALUE:
                    row.ErrorMessages.Remove(DuplicateKeyError);
                    existsSameValue = true;
                    break;

                case CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE:
                    row.ErrorMessages.Add(DuplicateKeyError);
                    break;

                case CONTAINS_KEY_RESULT.DOESNT_EXIST:
                    row.ErrorMessages.Remove(DuplicateKeyError);
                    break;
                }

                string originalValue = (string)row.Cells[KeyColumnName].Tag;
                ((DestinationKeyValueConflictResolver)ConflictResolver).TryAdd(originalValue, key, row, resxItem, row.DataSourceItem.Language);
                if (originalValue == null)
                {
                    row.Cells[KeyColumnName].Tag = key;
                }
            }

            row.UpdateErrorSetDisplay(); // update error messages

            if (row.ErrorMessages.Count == 0)
            {
                if (existsSameValue)   // set background color according to conflict type
                {
                    row.DefaultCellStyle.BackColor = ExistingKeySameValueColor;
                }
                else
                {
                    row.DefaultCellStyle.BackColor = Color.White;
                }
            }
        }
Beispiel #2
0
        public void Move(List <CodeStringResultItem> dataList, ref int errorRows)
        {
            // sort according to position
            dataList.Sort(new ResultItemsPositionCompararer <CodeStringResultItem>());

            for (int i = dataList.Count - 1; i >= 0; i--)
            {
                try {
                    // initialization of data
                    CodeStringResultItem resultItem   = dataList[i];
                    string              path          = resultItem.SourceItem.GetFullPath();
                    ReferenceString     referenceText = null;
                    bool                addUsingBlock = false;
                    CONTAINS_KEY_RESULT keyConflict   = CONTAINS_KEY_RESULT.DOESNT_EXIST;

                    if (resultItem.MoveThisItem) // row was checked in the toolwindow
                    {
                        Validate(resultItem);    // check that key, value and destination item was specifed and that row has no errors
                        if (!resultItem.DestinationItem.IsLoaded)
                        {
                            resultItem.DestinationItem.Load();
                        }
                        if (!loadedResxItems.Contains(resultItem.DestinationItem))
                        {
                            loadedResxItems.Add(resultItem.DestinationItem);
                        }

                        // check if such item already exists in destination file
                        keyConflict = resultItem.DestinationItem.GetKeyConflictType(resultItem.Key, resultItem.Value, true);
                        if (keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE)
                        {
                            throw new InvalidOperationException(string.Format("Key \"{0}\" already exists with different value.", resultItem.Key));
                        }
                        resultItem.Key = resultItem.DestinationItem.GetRealKey(resultItem.Key); // if key already exists, return its name (solves case-sensitivity problems)

                        NamespacesList usedNamespaces = GetUsedNamespacesFor(resultItem);

                        if (UseFullName || resultItem.MustUseFullName || (resultItem.Language == LANGUAGE.VB && resultItem.DestinationItem.IsProjectDefault(resultItem.SourceItem.ContainingProject)))   // reference will contain namespace
                        {
                            referenceText = new ReferenceString(resultItem.DestinationItem.Namespace, resultItem.DestinationItem.Class, resultItem.Key);
                            addUsingBlock = false; // no using block will be added
                        }
                        else
                        {
                            // use resolver whether it is ok to add using block
                            addUsingBlock = usedNamespaces.ResolveNewElement(resultItem.DestinationItem.Namespace, resultItem.DestinationItem.Class, resultItem.Key,
                                                                             resultItem.SourceItem.ContainingProject, out referenceText);
                        }
                        if (addUsingBlock)   // new using block will be added
                        {
                            if (!usedNamespacesCache.ContainsKey(resultItem.SourceItem))
                            {
                                usedNamespacesCache.Add(resultItem.SourceItem, new NamespacesList());
                            }
                            foreach (var pair in usedNamespacesCache)
                            {
                                if (!pair.Value.ContainsNamespace(resultItem.DestinationItem.Namespace))
                                {
                                    pair.Value.Add(resultItem.DestinationItem.Namespace, null, true);
                                }
                            }
                        }
                    }

                    if (RDTManager.IsFileOpen(path) && RDTManager.IsFileVisible(path))                                                    // file is open
                    {
                        if (resultItem.MoveThisItem || (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment)) // string literal in text will be modified (referenced or marked with comment)
                        {
                            if (!buffersCache.ContainsKey(path))
                            {
                                // load file's buffer
                                IVsTextLines textLines = DocumentViewsManager.GetTextLinesForFile(path, false);
                                buffersCache.Add(path, textLines);

                                IOleUndoManager m;
                                // get file's undo manager
                                int hr = textLines.GetUndoManager(out m);
                                Marshal.ThrowExceptionForHR(hr);
                                undoManagersCache.Add(path, m);
                            }
                        }

                        if (resultItem.MoveThisItem)
                        {
                            // perform the text replacement
                            MoveToResource(buffersCache[path], resultItem, referenceText);

                            if (resultItem.IsConst && resultItem.CodeModelSource is CodeVariable2)
                            {
                                CodeVariable2 codeVar = (CodeVariable2)resultItem.CodeModelSource;
                                codeVar.ConstKind = vsCMConstKind.vsCMConstKindNone;
                            }

                            if (addUsingBlock)
                            {
                                // add using block to the source file
                                int beforeLines, afterLines;
                                buffersCache[path].GetLineCount(out beforeLines);
                                resultItem.AddUsingBlock(buffersCache[path]);
                                buffersCache[path].GetLineCount(out afterLines);
                                int diff = afterLines - beforeLines;

                                // because of the previous step, it is necessary to adjust position of all not-yet referenced result items
                                for (int j = i; j >= 0; j--)
                                {
                                    var item = dataList[j];
                                    if (item.SourceItem == resultItem.SourceItem)
                                    {
                                        TextSpan ts = new TextSpan();
                                        ts.iEndIndex     = item.ReplaceSpan.iEndIndex;
                                        ts.iEndLine      = item.ReplaceSpan.iEndLine + diff;
                                        ts.iStartIndex   = item.ReplaceSpan.iStartIndex;
                                        ts.iStartLine    = item.ReplaceSpan.iStartLine + diff;
                                        item.ReplaceSpan = ts;
                                    }
                                }
                            }

                            // previous step (replace and possibly new using block) caused undo unit to be added - remove it
                            int unitsToRemoveCount    = (resultItem.IsConst && addUsingBlock ? 3 : (resultItem.IsConst || addUsingBlock ? 2 : 1));
                            List <IOleUndoUnit> units = undoManagersCache[path].RemoveTopFromUndoStack(unitsToRemoveCount);

                            // and add custom undo unit
                            AbstractUndoUnit newUnit = null;
                            if (keyConflict == CONTAINS_KEY_RESULT.DOESNT_EXIST)
                            {
                                newUnit = new MoveToResourcesUndoUnit(resultItem.Key, resultItem.Value, resultItem.DestinationItem);
                            }
                            else if (keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_SAME_VALUE)
                            {
                                newUnit = new MoveToResourcesReferenceUndoUnit(resultItem.Key);
                            }

                            newUnit.AppendUnits.AddRange(units);
                            undoManagersCache[path].Add(newUnit);
                        }
                        else if (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment)     // string literal should be marked with comment
                        {
                            AspNetStringResultItem aitem = resultItem as AspNetStringResultItem;

                            // this operation is only possible if string literal comes from C# code
                            if (resultItem is CSharpStringResultItem || (aitem != null && aitem.ComesFromCodeBlock && aitem.Language == LANGUAGE.CSHARP))
                            {
                                // add the comment
                                int c = MarkAsNoLoc(buffersCache[path], resultItem);

                                // add undo unit
                                List <IOleUndoUnit> units = undoManagersCache[path].RemoveTopFromUndoStack(1);
                                MarkAsNotLocalizedStringUndoUnit newUnit = new MarkAsNotLocalizedStringUndoUnit(resultItem.Value);
                                newUnit.AppendUnits.AddRange(units);
                                undoManagersCache[path].Add(newUnit);
                            }
                        }
                    }
                    else     // file is closed
                    // same as with open file, only operating with text, not buffers

                    {
                        if (resultItem.MoveThisItem || (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment))   // string literal will be modified
                        // load file's text into the cache
                        {
                            if (!filesCache.ContainsKey(path))
                            {
                                filesCache.Add(path, new StringBuilder(File.ReadAllText(path)));
                            }
                        }

                        if (resultItem.IsConst && resultItem.CodeModelSource is CodeVariable2)
                        {
                            CodeVariable2 codeVar = (CodeVariable2)resultItem.CodeModelSource;
                            fieldsToRemoveConst.Add(codeVar);
                        }

                        if (resultItem.MoveThisItem)
                        {
                            StringBuilder b = filesCache[path];

                            // perform the replacement
                            string insertText = resultItem.GetReferenceText(referenceText);
                            b.Remove(resultItem.AbsoluteCharOffset, resultItem.AbsoluteCharLength);
                            b.Insert(resultItem.AbsoluteCharOffset, insertText);

                            if (addUsingBlock)
                            {
                                // add using block
                                if (!newUsingsPlan.ContainsKey(path))
                                {
                                    newUsingsPlan.Add(path, new List <string>());
                                }
                                newUsingsPlan[path].Add(resultItem.DestinationItem.Namespace);
                            }
                        }
                        else if (MarkUncheckedStringsWithComment && !resultItem.IsMarkedWithUnlocalizableComment)
                        {
                            AspNetStringResultItem aitem = resultItem as AspNetStringResultItem;

                            if (resultItem is CSharpStringResultItem || (aitem != null && aitem.ComesFromCodeBlock && aitem.Language == LANGUAGE.CSHARP))
                            {
                                StringBuilder b = filesCache[path];
                                b.Insert(resultItem.AbsoluteCharOffset, resultItem.NoLocalizationComment);
                            }
                        }
                    }

                    if (resultItem.MoveThisItem && keyConflict == CONTAINS_KEY_RESULT.DOESNT_EXIST)
                    {
                        if (!resultItem.DestinationItem.IsInBatchMode)
                        {
                            resultItem.DestinationItem.BeginBatch();
                        }
                        // add the key to the ResX file
                        resultItem.DestinationItem.AddString(resultItem.Key, resultItem.Value);
                    }
                } catch (Exception ex) {
                    errorRows++;
                    VLOutputWindow.VisualLocalizerPane.WriteException(ex);
                }
            }

            // add using blocks to closed files texts
            foreach (var pair in newUsingsPlan)
            {
                foreach (string nmspc in pair.Value)
                {
                    AddUsingBlockTo(pair.Key, nmspc);
                }
            }

            // flush closed files texts
            foreach (var pair in filesCache)
            {
                if (RDTManager.IsFileOpen(pair.Key))
                {
                    RDTManager.SetIgnoreFileChanges(pair.Key, true);
                    File.WriteAllText(pair.Key, pair.Value.ToString());
                    RDTManager.SetIgnoreFileChanges(pair.Key, false);
                    RDTManager.SilentlyReloadFile(pair.Key);
                }
                else
                {
                    File.WriteAllText(pair.Key, pair.Value.ToString());
                }
            }

            // remove 'const' modifier from fields in closed files
            HashSet <ProjectItem> itemsToSave = new HashSet <ProjectItem>();

            foreach (CodeVariable2 codeVar in fieldsToRemoveConst)
            {
                codeVar.ConstKind = vsCMConstKind.vsCMConstKindNone;
                itemsToSave.Add(codeVar.ProjectItem);
            }
            foreach (ProjectItem item in itemsToSave)
            {
                item.Save(null);
            }

            foreach (ResXProjectItem item in loadedResxItems)
            {
                if (item.IsInBatchMode)
                {
                    item.EndBatch();
                }
                item.Unload();
            }
            if (errorRows > 0)
            {
                throw new Exception("Error occured while processing some rows - see Output window for details.");
            }
        }
Beispiel #3
0
        /// <summary>
        /// Executed on every change in window form
        /// </summary>
        private void ValidateData()
        {
            bool   existsFile = comboBox.Items.Count > 0; // there's at least one possible destination file
            string errorText  = null;
            bool   ok         = true;

            if (!existsFile)   // no destination file
            {
                ok        = false;
                errorText = "Project does not contain any useable resource files";
            }
            else
            {
                ResXProjectItem item = comboBox.SelectedItem as ResXProjectItem;
                if (!item.IsLoaded)
                {
                    item.Load();
                    VLDocumentViewsManager.SetFileReadonly(item.InternalProjectItem.GetFullPath(), true);
                }
                resultItem.DestinationItem = item;

                bool isKeyEmpty            = string.IsNullOrEmpty(keyBox.Text);
                bool isValidIdentifier     = keyBox.Text.IsValidIdentifier(resultItem.Language);
                bool hasOwnDesigner        = (item.DesignerItem != null || item.HasImplicitDesignerFile) && !item.IsCultureSpecific();
                bool identifierErrorExists = false;

                // determine whether current key name is valid
                switch (SettingsObject.Instance.BadKeyNamePolicy)
                {
                case BAD_KEY_NAME_POLICY.IGNORE_COMPLETELY:
                    identifierErrorExists = isKeyEmpty;     // only empty keys are invalid
                    break;

                case BAD_KEY_NAME_POLICY.IGNORE_ON_NO_DESIGNER:
                    identifierErrorExists = isKeyEmpty || (!isValidIdentifier && hasOwnDesigner);     // empty keys and invalid identifiers in ResX files with their own designer file
                    break;

                case BAD_KEY_NAME_POLICY.WARN_ALWAYS:
                    identifierErrorExists = isKeyEmpty || !isValidIdentifier;     // empty keys and invalid identifiers
                    break;
                }

                if (!identifierErrorExists)   // identifier ok - check for key name conflicts
                {
                    keyConflict = item.GetKeyConflictType(keyBox.Text, valueBox.Text, true);

                    Color backColor = Color.White;
                    switch (keyConflict)
                    {
                    case CONTAINS_KEY_RESULT.EXISTS_WITH_SAME_VALUE:     // key already exists and has the same value - ok
                        backColor = EXISTING_KEY_COLOR;
                        break;

                    case CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE:     // key exists with different value - error
                        errorText             = "Key is already present and has different value";
                        existingValueBox.Text = item.GetString(keyBox.Text);
                        backColor             = ERROR_COLOR;
                        break;

                    case CONTAINS_KEY_RESULT.DOESNT_EXIST:     // key doesn't exists - ok
                        backColor = Color.White;
                        break;
                    }

                    overwriteButton.Visible  = keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE;
                    inlineButton.Visible     = keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE;
                    existingValueBox.Visible = keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE;
                    existingLabel.Visible    = keyConflict == CONTAINS_KEY_RESULT.EXISTS_WITH_DIFF_VALUE;

                    keyBox.BackColor   = backColor;
                    valueBox.BackColor = backColor;
                }
                else
                {
                    errorText          = "Key is not a valid identifier";
                    keyBox.BackColor   = ERROR_COLOR;
                    valueBox.BackColor = Color.White;
                }

                ok = !identifierErrorExists && !overwriteButton.Visible;

                referenceText.ClassPart = item.Class;
                referenceText.KeyPart   = keyBox.Text;

                if (string.IsNullOrEmpty(item.Namespace))   // no namespace was found in designer file - error
                {
                    ok        = false;
                    errorText = "Cannot reference resources in this file, missing namespace";
                }
                else
                {
                    if (!usingBox.Checked || resultItem.MustUseFullName)   // force using full reference
                    {
                        referenceText.NamespacePart = item.Namespace;
                    }
                    else
                    {
                        referenceText.NamespacePart = null;
                    }
                }

                referenceLabel.Text = resultItem.GetReferenceText(referenceText);
            }

            okButton.Enabled = ok;
            if (ok)
            {
                errorLabel.Text = string.Empty;
            }
            else
            {
                errorLabel.Text = errorText;
            }
        }