예제 #1
0
        public EntryFieldRow(ClientEntry sourceEntry, EntryField sourceField)
        {
            this.SourceEntry = sourceEntry;
            this.SourceField = sourceField;

            Reset();
        }
예제 #2
0
        public AddEntryDialog(ClientEntry entry)
        {
            InitializeComponent();

            this.Text = "Rename Entry";
            this.ClientEntry = new ClientEntry() { Template = entry.Template, Name = entry.Name };

            clientEntryBindingSource.DataSource = this.ClientEntry;

            if (entry.Template != null)
                entryTemplateBindingSource.DataSource = new[] { entry.Template };

            templateComboBox.Enabled = false;
        }
예제 #3
0
 public void RemoveEntry(ClientEntry entry)
 {
     RemoveEntries(new[] { entry });
 }
예제 #4
0
 public void AddEntry(ClientEntry entry)
 {
     AddEntries(new[] { entry });
 }
예제 #5
0
 internal ClientEntryEventArgs(ClientEntry entry)
 {
     this.ClientEntries = new[] { entry };
 }
예제 #6
0
        public ConfirmDeleteDialog(ClientEntry entry)
        {
            InitializeComponent();

            mainInstructionLabel.Text = String.Format(mainInstructionLabel.Text, entry.Name, entry.Client.Name);
        }
        public DeleteCustomFieldDialog(ClientEntry container, EntryField field)
        {
            InitializeComponent();

            mainInstructionLabel.Text = String.Format(mainInstructionLabel.Text, field.Name, container.Name);
        }
예제 #8
0
 private void RemoveEntryFromListView(ClientEntry entry)
 {
     //find the item and remove it
     ListViewItem item = entryListView.Items.Cast<ListViewItem>().FirstOrDefault(i => i.Tag == entry);
     if (item != null)
         item.Remove();
 }
예제 #9
0
        private void DisplaySelectedEntry()
        {
            if (_activeEntry != null)
            {
                _activeEntry.CustomFieldAdded -= ActiveEntry_CustomFieldAdded;
                _activeEntry.CustomFieldRemoved -= ActiveEntry_CustomFieldRemoved;
            }

            _activeFields.Clear();

            if (entryListView.SelectedItems.Count > 0)
            {
                _activeEntry = entryListView.SelectedItems[0].Tag as ClientEntry;

                _activeEntry.CustomFieldAdded += new EventHandler<EntryFieldEventArgs>(ActiveEntry_CustomFieldAdded);
                _activeEntry.CustomFieldRemoved += new EventHandler<EntryFieldEventArgs>(ActiveEntry_CustomFieldRemoved);

                entryGroupBox.Text = _activeEntry.Template == null ? _activeEntry.Name : String.Format("{0} ({1})", _activeEntry.Name, _activeEntry.Template.Name);

                EntryNotes notes;
                if (!_entryNotes.TryGetValue(_activeEntry, out notes))
                {
                    notes = new EntryNotes() { Notes = _activeEntry.Notes };
                    _entryNotes.Add(_activeEntry, notes);
                }

                entryNotesBindingSource.DataSource = notes;
                notesTextBox.Enabled = true;

                addCustomFieldLink.Enabled = _activeEntry.Template == null || _activeEntry.Template.AllowCustomFields;
                removeCustomFieldLink.Enabled = _activeEntry.Template == null || _activeEntry.Template.AllowCustomFields;

                //display fields by creating temporary Row objects, which last as long as the client stays selected
                //this allows the user to jump from entry to entry within a client without losing changes
                Dictionary<EntryField, EntryFieldRow> rowCache = GetCurrentCachedEntryFieldRows();

                foreach (var f in _activeEntry.AllFields)
                {
                    EntryFieldRow row;
                    if (!rowCache.TryGetValue(f, out row))
                    {
                        row = new EntryFieldRow(_activeEntry, f);
                        rowCache.Add(f, row);
                    }

                    _activeFields.Add(row);
                }

                deleteEntryToolStripMenuItem.Enabled = true;
                renameEntryToolStripMenuItem.Enabled = true;

                //record the log entry
                this.CurrentDatabase.AddLogEntry(_activeEntry, UserLogEntryType.Access);
            }
            else
            {
                _activeEntry = null;
                _activeFields.Clear();
                entryGroupBox.Text = "(no entry selected)";
                entryNotesBindingSource.DataSource = typeof(EntryNotes);
                notesTextBox.Enabled = false;
                deleteEntryToolStripMenuItem.Enabled = false;
                renameEntryToolStripMenuItem.Enabled = false;
                addCustomFieldLink.Enabled = false;
                removeCustomFieldLink.Enabled = false;
            }
        }
예제 #10
0
 private void AddEntryToListView(ClientEntry entry)
 {
     var item = entryListView.Items.Add(entry.Name, entry.IconIndex);
     item.SubItems.Add(entry.Template != null ? entry.Template.Name : String.Empty);
     item.Tag = entry;
     entry.PropertyChanged += new PropertyChangedEventHandler(ClientEntry_PropertyChanged);
 }
예제 #11
0
        private void RefreshClientEntriesInternal(ClientRecord client)
        {
            //preparation
            int clientId = _clients[client];
            if (!_clients.TryGetKey(client, out clientId))
                throw new ArgumentException("The specified client is not in this database.");

            var newEntries = new List<ClientEntry>();
            var prevEntryIds = client.Entries.Select(e => _entries[e]).ToList();

            //Query the Database
            var getListCommand = new SqlCommand("sp_GetClientEntries", _connection) { CommandType = System.Data.CommandType.StoredProcedure };
            getListCommand.Parameters.Add(new SqlParameter("token", "null_token"));    //TODO: token will go here
            getListCommand.Parameters.Add(new SqlParameter("client_id", clientId));

            using (var reader = getListCommand.ExecuteReader())
            {
                //result set 1: entry list for the specified client
                while (reader.Read())
                {
                    ClientEntry entry;
                    int clientEntryDbId = (int)reader[0];

                    //index the entry if it is new
                    if (!_entries.TryGetItem(clientEntryDbId, out entry))
                    {
                        entry = new ClientEntry();
                        _entries.Add(clientEntryDbId, entry);
                        newEntries.Add(entry);
                    }

                    //update the properties of the entry, regardless if it existed before
                    entry.Name = (string)reader[2];
                    entry.IconIndex = (int)reader[3];
                    entry.Notes = WebUtility.HtmlDecode((reader[5] as string ?? String.Empty).Replace("<br>", Environment.NewLine));

                    //set the template, it will get updated later if it doesn't exist yet
                    //we index the new template right away
                    EntryTemplate template;
                    int templateId = (reader[4] == DBNull.Value) ? -1 : (int)reader[4];
                    if (templateId == -1)
                    {
                        template = null;    //orphaned record
                    }
                    else if (!_templates.TryGetItem(templateId, out template))
                    {
                        template = new EntryTemplate();
                        _templates.Add(templateId, template);
                    }
                    entry.Template = template;
                }

                //result set 2: template definition
                reader.NextResult();
                while (reader.Read())
                {
                    EntryTemplate template;
                    int templateDbId = (int)reader[0];

                    if (!_templates.TryGetItem(templateDbId, out template))
                        throw new InvalidOperationException("A template was returned that was not part of the first result set.");

                    //update the properties
                    template.Name = reader[1] as string;
                    template.IconIndex = (int)reader[2];
                    template.AllowCustomFields = (bool)reader[3];
                }

                //result set 3: fields for the previous templates
                reader.NextResult();
                while (reader.Read())
                {
                    EntryField templateField;
                    EntryTemplate template;
                    int templateFieldId = (int)reader[0];
                    int templateId = (int)reader[1];
                    if (!_templates.TryGetItem(templateId, out template))
                        throw new InvalidOperationException("A template field was returned that belongs to a template that was not returned in the previous result set.");

                    if (!_templateFields.TryGetItem(templateFieldId, out templateField))
                    {
                        templateField = new EntryField();
                        _templateFields.Add(templateFieldId, templateField);
                    }

                    if (!template.Fields.Contains(templateField))
                        template.AddField(templateField);

                    //update the properties
                    templateField.Name = reader[2] as string;
                    templateField.EntryType = (EntryFieldType)reader[3];
                    templateField.DefaultValue = reader[4] as string;
                }
                //TODO: remove any fields that were not returned

                //result set 4: field values
                reader.NextResult();
                while (reader.Read())
                {
                    int fieldValueId = (int)reader[0];
                    int entryId = (int)reader[1];

                    ClientEntry entry;
                    if (!_entries.TryGetItem(entryId, out entry))
                        throw new InvalidOperationException("A ClientEntry was returned that was not defined in a previous result set.");

                    int templateFieldId = (reader[2] == DBNull.Value) ? -1 : (int)reader[2];
                    string entryValue = reader[4] as string;

                    //indexing of fields values:
                    //  template field values are indexed by TFVR objects in the _templateFieldsById dictionary
                    //  custom field values are indexed by just the EntryField object in the _customFieldsById dictionary
                    if (templateFieldId == -1)
                    {
                        //custom field
                        string fieldName = reader[3] as string;
                        EntryField customField;
                        if (!_customFields.TryGetItem(fieldValueId, out customField))
                        {
                            customField = new EntryField() { Name = fieldName };    //todo: type
                            entry.AddCustomField(customField);
                            _customFields.Add(fieldValueId, customField);
                        }

                        //update the name and value
                        customField.Name = fieldName;
                        entry.SetValue(customField, DataSecurity.DecryptStringAES(entryValue));
                    }
                    else
                    {
                        //find the template EntryField by ID
                        EntryField templateField;
                        if (_templateFields.TryGetItem(templateFieldId, out templateField))
                        {
                            //save the ID of the field value for saving later
                            if (!_templateValues.Values.Any(tfvr => tfvr.ClientEntry == entry && tfvr.TemplateField == templateField))
                                _templateValues.Add(fieldValueId, new TemplateFieldValueRelation() { ClientEntry = entry, TemplateField = templateField });

                            entry.SetValue(templateField, DataSecurity.DecryptStringAES(entryValue));
                        }
                        else
                        {
                            throw new InvalidOperationException("A template field was returned that cannot be matched to an existing template.");
                        }
                    }
                }
                //TODO: remove any fields that were not returned
            }

            //clean up the internal list, and raise events for the UI
            var deletedEntryIds = prevEntryIds.Except(_entries.Keys).ToList();
            if (deletedEntryIds.Any())
            {
                var deletedEntries = new List<ClientEntry>();
                foreach (var id in deletedEntryIds)
                {
                    var entry = _entries[id];
                    deletedEntries.Add(entry);
                    _entries.Remove(entry);
                }

                client.RemoveEntries(deletedEntries);
            }

            if (newEntries.Any())
                client.AddEntries(newEntries);
        }
예제 #12
0
        private int GetOrCreateFieldValueId(ClientEntry entry, EntryField field)
        {
            int match = -1;

            bool isTemplate = field.Container is EntryTemplate;
            if (isTemplate)
            {
                var matches = _templateValues
                    .Where(kvp => kvp.Value.ClientEntry == entry && kvp.Value.TemplateField == field)
                    .ToList();

                if (matches.Count() == 1)
                    match = matches.First().Key;
                else if (matches.Count() > 1)
                    throw new InvalidOperationException("Database inconsistency detected.  Restart Pogs before continuting.");
            }
            else if (field.Container is ClientEntry && _customFields.ContainsItem(field))
            {
                match = _customFields[field];
            }

            if (match != -1)
            {
                return match;
            }
            else
            {
                var addCommand = new SqlCommand("sp_AddFieldValue", _connection) { CommandType = System.Data.CommandType.StoredProcedure };
                addCommand.Parameters.Add(new SqlParameter("token", "null_token"));    //TODO: token will go here
                addCommand.Parameters.Add(new SqlParameter("entry_id", _entries[entry]));
                addCommand.Parameters.Add(new SqlParameter("template_field_id", isTemplate ? (object)_templateFields[field] : DBNull.Value));
                addCommand.Parameters.Add(new SqlParameter("name", isTemplate ? (object)DBNull.Value : (object)field.Name));
                addCommand.Parameters.Add(new SqlParameter("value", DBNull.Value));

                //assign the IDs
                int newId = (int)addCommand.ExecuteScalar();
                if (isTemplate)
                    _templateValues.Add(newId, new TemplateFieldValueRelation() { ClientEntry = entry, TemplateField = field });
                else
                    _customFields.Add(newId, field);

                return newId;
            }
        }
예제 #13
0
        public void AddLogEntry(ClientEntry entry, UserLogEntryType entryType)
        {
            //preconditions
            if (!this.Connected)
                throw new InvalidOperationException("Cannot add the log entry because the database is not connected.");
            if (!this.Authenticated)
                throw new InvalidOperationException("Cannot add the log entry because the current user is not authenticated with the Database.");
            if (entry == null)
                throw new ArgumentNullException("entry");
            if (entryType != UserLogEntryType.Delete && !_entries.ContainsItem(entry))
                throw new ArgumentException("The entry specified is not in this database.");
            if (entryType == UserLogEntryType.Delete && _entries.ContainsItem(entry))
                throw new ArgumentException("A delete log entry cannot be written because the ClientEntry specified is in this database.");

            //prepare the description
            string description = String.Format("{0}: {1}", entry.Client.Name, entry.Name);
            var client = entry.Client;

            AddLogEntryInternal(entryType, client, description);
        }