Exemple #1
0
        private void add_note_to_ui(note_item last_note) {
            bool add_to_ui = !last_note.deleted || (last_note.deleted && showDeletedLines.Checked);
            if (!add_to_ui)
                return;

            int insert_idx = -1;
            if (last_note.reply_id != "") {
                // it's a note on reply to another note
                for (int note_idx = 0; note_idx < notesCtrl.GetItemCount() && insert_idx < 0; ++note_idx) {
                    var i = notesCtrl.GetItem(note_idx).RowObject as note_item;
                    if (i.note_id == last_note.reply_id) 
                        insert_idx = note_idx + 1;
                }
            } else {
                // new note
                if (!last_note.is_note_header)
                    for (int note_idx = 0; note_idx < notesCtrl.GetItemCount(); ++note_idx) {
                        var i = notesCtrl.GetItem(note_idx).RowObject as note_item;
                        string line_id = i.line_id != cur_line_id_ ? i.line_id : find_cur_line_id();

                        if (line_id == last_note.line_id) {
                            insert_idx = note_idx + 1;
                            bool insert_at_the_end = i.line_id == cur_line_id_;
                            if (insert_at_the_end) {
                                // we need to update the line, so that it does not point to current-line anymore
                                i.line_id = line_id;
                            }
                        }
                    }
                else
                    // it's a new note header, add at the end
                    insert_idx = notesCtrl.GetItemCount();
            }
            Debug.Assert( insert_idx >= 0);
            if (insert_idx >= 0) {
                ++ignore_change_;
                notesCtrl.InsertObjects(insert_idx, new object[] {last_note});
                // now, select it as well
                notesCtrl.SelectObject(last_note);
                // ... so that it recomputes its UI index correctly
                notesCtrl.RefreshObject(last_note);
                --ignore_change_;
                notesCtrl.EnsureVisible(insert_idx);
                refresh_note(last_note);
            }
        }
Exemple #2
0
        // this sets the line the user is viewing - by default, this is what the user is commenting on
        private void set_current_line_impl(line l) {
            if (cur_line.idx == l.idx && cur_line.view_name == l.view_name)
                return; // we're already there

            if (l.idx < 0) {
                ++ignore_change_;
                for (int idx = 0; idx < notesCtrl.GetItemCount(); ++idx) {
                    var i = notesCtrl.GetItem(idx).RowObject as note_item; 
                    if ( i.is_cur_line)
                        notesCtrl.RemoveObject(i);
                }
                --ignore_change_;
            }

            cur_line.copy_from(l);

            if (l.idx < 0) {
                ++ignore_change_;
                notesCtrl.SelectedIndex = -1;
                --ignore_change_;
                update_cur_note_controls();
                return;
            }

            /* Possibilities:
            
            - case 1 - there are already notes on this line

                1a - there are already notes on this line, and the selection is already one of them
                1b - there are already notes on this line, and the selection is on another note (or nowhere)

            - case 2 - there are no notes on this line
            */
            note_item header = null;
            for (int idx = 0; idx < notesCtrl.GetItemCount() && header == null ; ++idx) {
                var i = notesCtrl.GetItem(idx).RowObject as note_item;
                if (i.is_note_header && lines_[i.line_id].idx == l.idx && !i.is_cur_line) 
                    header = i;
            }

            bool last_note_is_cur_line = notesCtrl.GetItemCount() > 0 && (notesCtrl.GetItem(notesCtrl.GetItemCount() - 1).RowObject as note_item).is_cur_line;
            if (header != null) {
                // already a note on this line, not needed now
                if (last_note_is_cur_line)
                    notesCtrl.RemoveObject(notesCtrl.GetItem(notesCtrl.GetItemCount() - 1).RowObject);

                int sel = notesCtrl.SelectedIndex;
                var sel_item = sel >= 0 ? notesCtrl.GetItem(sel).RowObject as note_item : null;
                if (sel_item != null && sel_item.line_id == header.line_id)
                    // 1a - on a note from this line
                    return;

                // 1b - on a note from another line
                // I will select the last note from this user
                var last = ui_find_last_note_from_cur_user(header.line_id);
                notesCtrl.SelectObject( last);
                notesCtrl.EnsureModelVisible(last);
            } else {
                // 2 - no notes on this line
                if (!last_note_is_cur_line) {
                    var new_ = new note_item(this, next_guid, cur_line_id_, false, DateTime.UtcNow);
                    notesCtrl.AddObject(new_);
                    refresh_note( new_);
                }
                var last = notesCtrl.GetItem(notesCtrl.GetItemCount() - 1).RowObject as note_item;
                refresh_note(last);

                bool focus_on_notes = win32.focused_ctrl() == notesCtrl;
                if (notesCtrl.SelectedIndex < 0 || !focus_on_notes) {
                    // select the "last line"
                    notesCtrl.SelectedIndex = notesCtrl.GetItemCount() - 1;
                    notesCtrl.EnsureVisible( notesCtrl.GetItemCount() - 1);
                }
            }

            update_cur_note_controls();
        }
Exemple #3
0
        // returns the ID assigned to this note that we're adding;
        // if null, something went wrong
        //
        // note_id - the unique ID of the note, or "" if a new unique ID is to be created
        //           the reason we have this is that we can persist notes (together with their IDs)
        private note_item add_note(line l, note n, string note_id, string reply_to_note_id, bool deleted, DateTime utc_added) {
            // a note: can be added on a line, or as reply to someone
            // new notes: always at the end

            string line_id = "";
            // ... first, try to see if we already have a valid line
            var found_line = lines_.FirstOrDefault(x => x.Key != cur_line_id_ && x.Value == l);
            if ( found_line.Value == null)
                found_line = lines_.FirstOrDefault(x => x.Value == l);
            Debug.Assert(found_line.Value != null);
            if (found_line.Key == cur_line_id_) {
                // it's the current line
                line_id = next_guid;
                lines_.Add(line_id, l);
            } 
            else 
                line_id = found_line.Key;

            note_id = note_id != "" ? note_id : next_guid;
            // ... this note should not exist already
            Debug.Assert( notes_sorted_by_line_index_.Count(x => x.note_id == note_id) == 0);
            if ( reply_to_note_id != "")
                // note we're replying to should exist already
                Debug.Assert( notes_sorted_by_line_index_.Count(x => x.note_id == reply_to_note_id) == 1);

            var new_ = new note_item(this, n, note_id, reply_to_note_id, line_id, deleted, utc_added);
            bool inserted = false;
            if (reply_to_note_id != "") {
                // add this note as the last reply to this reply note
                var note = notes_sorted_by_line_index_.FirstOrDefault(x => x.line_id == line_id);
                // when it's a reply, we need to find the original note!
                Debug.Assert(note != null);
                if (note != null) {
                    Debug.Assert(note.is_note_header);
                    // everything following this, is related to this line (until we get to next line)
                    int idx_note = notes_sorted_by_line_index_.IndexOf(note);
                    for (; idx_note < notes_sorted_by_line_index_.Count && !inserted; idx_note++)
                        if (notes_sorted_by_line_index_[idx_note].line_id == line_id) {
                            if (reply_to_note_id != "") {
                                // in this case, look for this note (that we're replying to)
                                if (notes_sorted_by_line_index_[idx_note].note_id == reply_to_note_id) {
                                    log_notes_sorted_idx(idx_note + 1, new_);
                                    notes_sorted_by_line_index_.Insert(idx_note + 1, new_);                                    
                                    inserted = true;
                                }
                            } else {
                                // look for the last note about this line, and insert it after that
                                if ( idx_note < notes_sorted_by_line_index_.Count - 1)
                                    if (notes_sorted_by_line_index_[idx_note + 1].line_id != line_id) {
                                        // found the last note that relates to this line
                                        notes_sorted_by_line_index_.Insert(idx_note + 1, new_);
                                        log_notes_sorted_idx(idx_note + 1, new_);
                                        inserted = true;                                        
                                    }
                            }
                        } else
                            // went to next line
                            break;
                }
            }
            else {
                var note = notes_sorted_by_line_index_.FirstOrDefault(x => x.line_id == line_id);
                if (note != null) {
                    // in this case, there may be other notes - we're adding it to the end (as last note on this line)
                    Debug.Assert(note.is_note_header);
                    int idx = notes_sorted_by_line_index_.IndexOf(note);
                    for ( ; idx < notes_sorted_by_line_index_.Count; ++idx)
                        if ( idx < notes_sorted_by_line_index_.Count - 1)
                            if (notes_sorted_by_line_index_[idx + 1].line_id != line_id)
                                break;
                    if (idx < notes_sorted_by_line_index_.Count) {
                        log_notes_sorted_idx(idx + 1, new_);
                        notes_sorted_by_line_index_.Insert(idx + 1, new_);
                    } else {
                        log_notes_sorted_idx(-1, new_);
                        notes_sorted_by_line_index_.Add(new_);
                    }
                    inserted = true;
                } else {
                    // this is the first entry that relates to this line
                    // ... find the note before which we should insert ourselves
                    int line_index = lines_[line_id].idx;
                    note = notes_sorted_by_line_index_.FirstOrDefault(x => lines_[x.line_id].idx > line_index);

                    var header = new note_item(this, next_guid, line_id, deleted, utc_added);
                    if (note != null) {
                        int idx = notes_sorted_by_line_index_.IndexOf(note);
                        bool has_header = note.is_note_header && note.line_id == line_id;
                        if (!has_header) {
                            log_notes_sorted_idx(idx, header);
                            notes_sorted_by_line_index_.Insert(idx, header);
                            log_notes_sorted_idx(idx + 1, new_);
                            notes_sorted_by_line_index_.Insert(idx + 1, new_);
                        } else {
                            // header is already added
                            if (header.deleted && !deleted)
                                // in this case, the header was deleted (probably we removed all items related to this line a while ago,
                                // and now we have added a new note here)
                                header.deleted = false;
                            log_notes_sorted_idx(idx, new_);
                            notes_sorted_by_line_index_.Insert(idx, new_);
                        }
                    } else {
                        log_notes_sorted_idx(-1, header);
                        log_notes_sorted_idx(-1, new_);
                        notes_sorted_by_line_index_.Add(header);
                        notes_sorted_by_line_index_.Add(new_);
                    }
                    inserted = true;
                }
            }
            Debug.Assert(inserted);

            // update the UI
            if (inserted)
                add_note_to_ui(new_);

            dirty_ = true;
            return new_;
        }
Exemple #4
0
 private void log_notes_sorted_idx(int idx, note_item n) {
     if (idx >= 0 && idx < notes_sorted_by_line_index_.Count) 
         logger.Info("[notes] insert " + n.friendly_note + " before " + notes_sorted_by_line_index_[idx].friendly_note);
     else 
         logger.Info("[notes] adding " + n.friendly_note + " at the end");
 }
Exemple #5
0
 // the only time this can get called is when loading an already saved configuration
 private note_item add_note_header(string line_id, string note_id, bool deleted, DateTime utc_added) {
     Debug.Assert(note_id != "");
     Debug.Assert(line_id != cur_line_id_ && lines_.ContainsKey(line_id));
     var new_ = new note_item(this, note_id, line_id, deleted, utc_added );
     notes_sorted_by_line_index_.Add(new_);
     add_note_to_ui(new_);
     return new_;
 }
Exemple #6
0
        private void refresh_note(note_item i) {
            notesCtrl.RefreshObject(i);

            var item = notesCtrl.ModelToItem(i);

            OLVListSubItem idx = item.GetSubItem(0), line = item.GetSubItem(1), text = item.GetSubItem(2);
            idx.ForeColor = i.idx_fg;
            line.ForeColor = i.line_fg;
            text.ForeColor = i.text_fg;

            idx.BackColor = line.BackColor = text.BackColor = i.bg;

            line.Font = i.font;
            text.Font = i.font;
        }
Exemple #7
0
        private static Tuple<Dictionary<string, line>, List<note_item>> load_settings_file(note_ctrl self, string file_name) {
            Dictionary<string, line> lines = new Dictionary<string, line>();
            List<note_item> notes = new List<note_item>();

            settings_file sett = new settings_file(file_name);
            // first, load lines
            int line_count = int.Parse(sett.get("line_count", "0"));
            for (int idx = 0; idx < line_count; ++idx) {
                string prefix = "line." + idx + ".";
                line l = new line();
                l.idx = int.Parse(sett.get(prefix + "index", "0"));
                l.view_name = sett.get(prefix + "view_name");
                l.msg = sett.get(prefix + "msg");
                var id = sett.get(prefix + "id", "");
                lines.Add(id, l);
            }

            // load notes
            // if author name = ourselves -> made_by_current_user = true
            int note_count = int.Parse(sett.get("note_count", "0"));
            for (int idx = 0; idx < note_count; ++idx) {
                string prefix = "note." + idx + ".";
                note n = null;
                string author_name = sett.get(prefix + "author_name");
                if (author_name != "") {
                    n = new note() {author_name = author_name};
                    n.author_initials = sett.get(prefix + "author_initials");
                    n.author_color = util.str_to_color(sett.get(prefix + "author_color"));
                    n.note_text = sett.get(prefix + "note_text");
                }
                bool deleted = sett.get(prefix + "deleted", "0") != "0";
                var note_id = sett.get(prefix + "note_id", "");
                var reply_id = sett.get(prefix + "reply_id", "");
                var line_id = sett.get(prefix + "line_id", "");
                long ticks = long.Parse(sett.get(prefix + "added_at", "0"));
                note_item note;
                if (n != null)
                    note = new note_item(self, n, note_id, reply_id, line_id, deleted, new DateTime(ticks));
                else
                    note = new note_item(self, note_id, line_id, deleted, new DateTime(ticks));
                notes.Add(note);
            }
            return new Tuple<Dictionary<string, line>, List<note_item>>(lines, notes);
        }