summaryrefslogtreecommitdiffstats
path: root/src/message_thread.hh
blob: 4bee766b95b3df193fd3c3b9350fb9290eddecfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# pragma once

# include <notmuch.h>
# include <gmime/gmime.h>

# include "proto.hh"
# include "astroid.hh"
# include "utils/address.hh"

namespace Astroid {
  class Message : public Glib::Object {
    friend MessageThread;

    public:
      Message ();
      Message (ustring _fname);
      Message (ustring _mid, ustring _fname);
      Message (notmuch_message_t *, int _level);
      Message (GMimeMessage *);
      Message (GMimeStream *);
      Message (refptr<NotmuchMessage>, int _level = 0);
      ~Message ();

      ustring fname;
      ustring mid;
      ustring safe_mid ();
      ustring tid;
      refptr<NotmuchMessage> nmmsg;
      bool    in_notmuch;
      bool    has_file;
      bool    missing_content; // file does not have a gmimeobject nor a file, use
                               // notmuch cache. essentially means that the
                               // db is out of sync.
      ustring get_filename (ustring appendix = "");

      void load_message_from_file (ustring);
      void load_message (GMimeMessage *);
      void load_notmuch_cache ();

      void on_message_updated (Db *, ustring);
      void refresh (Db *);

      GMimeMessage * message = NULL;
      refptr<Chunk>     root;
      int level = 0;

      ustring sender;
      ustring subject;
      InternetAddressList * to ();
      InternetAddressList * cc ();
      InternetAddressList * bcc ();
      InternetAddressList * other_to ();

      /* address list with all addresses in all headers beginning with to
       * and ending with from */
      AddressList all_to_from ();

      ustring references;
      ustring inreplyto;
      ustring reply_to;
      AddressList list_post ();

      time_t  time;
      ustring date ();
      ustring date_asctime ();
      ustring pretty_date ();
      ustring pretty_verbose_date (bool include_short = false);
      std::vector<ustring> tags;

      ustring plain_text (bool fallback_html = false);
      ustring quote ();
      std::vector<refptr<Chunk>> attachments ();
      refptr<Chunk> get_chunk_by_id (int id);

      std::vector<refptr<Chunk>> mime_messages ();

      /* used by editmessage, returns the same as attachments () and
       * mime_messages (), but in the correct order. */
      std::vector<refptr<Chunk>> mime_messages_and_attachments ();

      std::vector<refptr<Chunk>> all_parts ();

      refptr<Glib::ByteArray> contents ();
      refptr<Glib::ByteArray> raw_contents ();

      bool is_patch ();
      bool is_different_subject ();
      bool is_encrypted ();
      bool is_signed ();
      bool is_list_post ();
      bool has_tag (ustring);

      GMimeMessage * decrypt ();

      void save ();
      void save_to (ustring);

      /* message changed signal */
      typedef enum {
        MESSAGE_TAGS_CHANGED,
        MESSAGE_REMOVED,
      } MessageChangedEvent;

      typedef sigc::signal <void, Db *, Message *, MessageChangedEvent> type_signal_message_changed;
      type_signal_message_changed signal_message_changed ();

    protected:
      void emit_message_changed (Db *, MessageChangedEvent);
      type_signal_message_changed m_signal_message_changed;

      bool subject_is_different = true;
      bool process = true;
  };

  /* exceptions */
  class message_error : public std::runtime_error {
    public:
      message_error (const char *);

  };

  class UnprocessedMessage : public Message {
    public:
      UnprocessedMessage (ustring _fname);
      UnprocessedMessage (ustring _mid, ustring _fname);
      UnprocessedMessage (GMimeStream *);
      UnprocessedMessage (GMimeMessage *);
      UnprocessedMessage (notmuch_message_t *, int _level);
  };

  class MessageThread : public Glib::Object {
    public:
      MessageThread ();
      MessageThread (refptr<NotmuchThread>);
      ~MessageThread ();

      bool in_notmuch;
      ustring get_subject ();
      bool has_tag (ustring);

    private:
      ustring subject = "";
      ustring first_subject = "";
      void set_first_subject (ustring);
      bool first_subject_set = false;
      bool subject_is_different (ustring);

      void on_thread_updated (Db * db, ustring tid);
      void on_thread_changed (Db * db, ustring tid);

    public:
      refptr<NotmuchThread> thread;
      std::vector<refptr<Message>> messages;

      std::vector<refptr<Message>> messages_by_time ();

      void load_messages (Db *);
      void add_message (ustring);
      void add_message (refptr<Chunk>);
      void add_message (refptr<Message>);
  };

}