void GPG::Key::getDescription(std::vector<std::string> &descrArray, size_t width) { std::string keyDescr=longname; do { std::vector<unicode_char> unicode_buf; size_t p=keyDescr.find('\n'); if (p == std::string::npos) { unicode::iconvert::convert(keyDescr, unicode_default_chset(), unicode_buf); keyDescr=""; } else { unicode::iconvert::convert(keyDescr.substr(0, p), unicode_default_chset(), unicode_buf); keyDescr=keyDescr.substr(p+1); } std::vector< std::vector<unicode_char> > wrapped_text; std::back_insert_iterator<std::vector< std::vector <unicode_char> > > insert_iter(wrapped_text); unicodewordwrap(unicode_buf.begin(), unicode_buf.end(), unicoderewrapnone(), insert_iter, width, true); for (std::vector< std::vector<unicode_char> >::const_iterator b(wrapped_text.begin()), e(wrapped_text.end()); b != e; ++b) { descrArray.push_back(unicode::iconvert ::convert(*b, unicode_default_chset()) ); } } while (keyDescr.size() > 0); }
CursesMultilineLabel::CursesMultilineLabel(CursesContainer *parent, std::string textArg, Curses::CursesAttr attributeArg) : Curses(parent), width(0), attribute(attributeArg) { mail::iconvert::convert(textArg, unicode_default_chset(), text); }
static int conv_unicode(char **text, const char *fromChset, const char *toChset) { int err; char *p; if (!toChset) toChset=unicode_default_chset(); if (!fromChset || !*fromChset) return 0; p=libmail_u_convert_tobuf(*text, fromChset, toChset, &err); if (p && err) { free(p); p=NULL; } if (!p) return (-1); free(*text); *text=p; return (0); }
static int conv_unicode(char **text, const char *fromChset, const struct unicode_info *toChset) { #if HAVE_UNICODE const struct unicode_info *u=unicode_find(fromChset); if (toChset == NULL) { toChset=unicode_find(unicode_default_chset()); if (!toChset) toChset=&unicode_ISO8859_1; } if (u) { char *p=unicode_xconvert(*text, u, toChset); if (!p) return (-1); free(*text); *text=p; } #endif return (0); }
void CursesMultilineLabel::setText(std::string newText) { erase(); text.clear(); mail::iconvert::convert(newText, unicode_default_chset(), text); init(); draw(); }
int main() { int i; const char *c, *d; for (i=0; unicode_chsetlist[i].chsetname; i++) printf("chset=%s\n", unicode_chsetlist[i].chsetname); c=unicode_default_chset(); d=unicode_find(c)->chset; printf("default_chset=%s\n", c); printf("real_default_chset=%s\n", d); exit(0); return (0); }
void Gettext::Key::init() { if (keys.size() > 0) return; // Already wuz here const char *p=gettext(keyname); while (p && *p) { if (*p++ == ':') break; } std::string n(p); // gettext has problems with a literal \x04, so provide an alternative std::string::iterator b, e, q; for (b=n.begin(), e=n.end(), q=b; b != e; ++b) { if (*b == '\\') { std::string::iterator c=b; if (++c != e && *c++ == '\\' && c != e) { b=c; *q++ = *b & 31; continue; } } *q++=*b; } n.erase(q, b); unicode::iconvert::convert(n, unicode_default_chset(), keys); }
int main(int argc, char **argv) { int argn; FILE *tmpfp; struct rfc2045 *rfcp; struct mimeautoreply_s replyinfo; const char *subj=0; const char *txtfile=0, *mimefile=0; const char *mimedsn=0; int nosend=0; const char *replymode="reply"; int replytoenvelope=0; int donotquote=0; const char *forwardsep="--- Forwarded message ---"; const char *replysalut="%F writes:"; struct rfc2045src *src; setlocale(LC_ALL, ""); charset=unicode_default_chset(); sender=NULL; for (argn=1; argn < argc; argn++) { char optc; char *optarg; if (argv[argn][0] != '-') break; if (strcmp(argv[argn], "--") == 0) { ++argn; break; } optc=argv[argn][1]; optarg=argv[argn]+2; if (!*optarg) optarg=NULL; switch (optc) { case 'c': if (!optarg && argn+1 < argc) optarg=argv[++argn]; if (optarg && *optarg) { char *p=libmail_u_convert_tobuf("", optarg, libmail_u_ucs4_native, NULL); if (!p) { fprintf(stderr, "Unknown charset: %s\n", charset); exit(1); } free(p); charset=optarg; } continue; case 't': if (!optarg && argn+1 < argc) optarg=argv[++argn]; txtfile=optarg; continue; case 'm': if (!optarg && argn+1 < argc) optarg=argv[++argn]; mimefile=optarg; continue; case 'r': if (!optarg && argn+1 < argc) optarg=argv[++argn]; recips=optarg; continue; case 'M': if (!optarg && argn+1 < argc) optarg=argv[++argn]; mimedsn=optarg; continue; case 'd': if (!optarg && argn+1 < argc) optarg=argv[++argn]; dbfile=optarg; continue; case 'e': replytoenvelope=1; continue; case 'T': if (!optarg && argn+1 < argc) optarg=argv[++argn]; if (optarg && *optarg) replymode=optarg; continue; case 'N': donotquote=1; continue; case 'F': if (!optarg && argn+1 < argc) optarg=argv[++argn]; if (optarg && *optarg) forwardsep=optarg; continue; case 'S': if (!optarg && argn+1 < argc) optarg=argv[++argn]; if (optarg && *optarg) replysalut=optarg; continue; case 'D': if (!optarg && argn+1 < argc) optarg=argv[++argn]; interval=optarg ? atoi(optarg):1; continue; case 'A': if (!optarg && argn+1 < argc) optarg=argv[++argn]; if (optarg) { struct header **h; for (h= &extra_headers; *h; h= &(*h)->next) ; if ((*h=malloc(sizeof(struct header))) == 0 || ((*h)->buf=strdup(optarg)) == 0) { perror("malloc"); exit(EX_TEMPFAIL); } (*h)->next=0; } continue; case 's': if (!optarg && argn+1 < argc) optarg=argv[++argn]; subj=optarg; continue; case 'f': if (optarg && *optarg) { sender=strdup(optarg); } else { sender=getenv("SENDER"); if (!sender) continue; sender=strdup(sender); } if (sender == NULL) { perror("malloc"); exit(1); } continue; case 'n': nosend=1; continue; default: usage(); } } if (!txtfile && !mimefile) usage(); if (txtfile && mimefile) usage(); tmpfp=tmpfile(); if (!tmpfp) { perror("tmpfile"); exit(1); } rfcp=savemessage(tmpfp); if (fseek(tmpfp, 0L, SEEK_SET) < 0) { perror("fseek(tempfile)"); exit(1); } read_headers(tmpfp); if (sender == NULL || *sender == 0) check_sender(); check_dsn(); check_recips(); #ifdef DbObj check_db(); #endif src=rfc2045src_init_fd(fileno(tmpfp)); memset(&replyinfo, 0, sizeof(replyinfo)); replyinfo.info.src=src; replyinfo.info.rfc2045partp=rfcp; replyinfo.info.voidarg=&replyinfo; replyinfo.info.write_func=mimeautoreply_write_func; replyinfo.info.writesig_func=mimeautoreply_writesig_func; replyinfo.info.myaddr_func=mimeautoreply_myaddr_func; replyinfo.info.replymode=replymode; replyinfo.info.replytoenvelope=replytoenvelope; replyinfo.info.donotquote=donotquote; replyinfo.info.replysalut=replysalut; replyinfo.info.forwarddescr="Forwarded message"; replyinfo.info.mailinglists=""; replyinfo.info.charset=charset; replyinfo.info.subject=subj; replyinfo.info.forwardsep=forwardsep; if (mimedsn && *mimedsn) { replyinfo.info.dsnfrom=mimedsn; replyinfo.info.replymode="replydsn"; } if (mimefile) { if ((replyinfo.contentf=fopen(mimefile, "r")) == NULL) { perror(mimefile); exit(1); } { struct rfc2045 *rfcp=rfc2045_alloc(); static const char mv[]="Mime-Version: 1.0\n"; char buf[BUFSIZ]; int l; const char *content_type; const char *content_transfer_encoding; const char *charset; rfc2045_parse(rfcp, mv, sizeof(mv)-1); while ((l=fread(buf, 1, sizeof(buf), replyinfo.contentf) ) > 0) { rfc2045_parse(rfcp, buf, l); } if (l < 0 || fseek(replyinfo.contentf, 0L, SEEK_SET) < 0) { perror(mimefile); exit(1); } rfc2045_mimeinfo(rfcp, &content_type, &content_transfer_encoding, &charset); if (strcasecmp(content_type, "text/plain")) { fprintf(stderr, "%s must specify text/plain MIME type\n", mimefile); exit(1); } { char *p=NULL; if (charset) p=libmail_u_convert_tobuf("", charset, libmail_u_ucs4_native, NULL); if (!p) { fprintf(stderr, "Unknown charset in %s\n", mimefile); exit(1); } free(p); replyinfo.info.charset=strdup(charset); } rfc2045_free(rfcp); } replyinfo.info.content_set_charset=copy_headers; replyinfo.info.content_specify=copy_body; } else if (txtfile) { if ((replyinfo.contentf=fopen(txtfile, "r")) == NULL) { perror(mimefile); exit(1); } replyinfo.info.content_specify=copy_body; } if (replyinfo.contentf) fcntl(fileno(replyinfo.contentf), F_SETFD, FD_CLOEXEC); if (nosend) replyinfo.outf=stdout; else { replyinfo.outf=tmpfile(); if (replyinfo.outf == NULL) { perror("tmpfile"); exit(1); } } { struct header *h; for (h=extra_headers; h; h=h->next) fprintf(replyinfo.outf, "%s\n", h->buf); } fprintf(replyinfo.outf, "Precedence: junk\n" "Auto-Submitted: auto-replied\n"); if (rfc2045_makereply(&replyinfo.info) < 0 || fflush(replyinfo.outf) < 0 || ferror(replyinfo.outf) || (!nosend && ( fseek(replyinfo.outf, 0L, SEEK_SET) < 0 || (close(0), dup(fileno(replyinfo.outf))) < 0) )) { perror("tempfile"); exit(1); } fclose(replyinfo.outf); fcntl(0, F_SETFD, 0); rfc2045_free(rfcp); rfc2045src_deinit(src); if (!nosend) opensendmail(argn, argc, argv); return (0); }
void CursesFileReq::doresized() { int w=getWidth(); int c=filenameField.getCol(); filenameField.setWidth(c > w ? 1: w-c); // If too narrow fo the full directory name, truncate it. c=directoryName.getCol(); size_t dls=c < w ? w-c:1; std::vector<unicode_char> directoryW; mail::iconvert::convert(currentDir, unicode_default_chset(), directoryW); size_t directoryW_size; { widecharbuf wc; wc.init_unicode(directoryW.begin(), directoryW.end()); wc.expandtabs(0); wc.tounicode(directoryW); directoryW_size=wc.wcwidth(0); } if (directoryW_size > dls) { std::vector<unicode_char>::iterator b, e, c, lastSlash; b=directoryW.begin(); e=directoryW.end(); lastSlash=b; for (c=b; c != e; ) { if (*c++ == '/') lastSlash=c; } std::vector<unicode_char> replVector; replVector.push_back('/'); replVector.push_back('.'); replVector.push_back('.'); replVector.push_back('.'); replVector.push_back('/'); replVector.insert(replVector.end(), lastSlash, e); size_t suffixSize; { widecharbuf wc; wc.init_unicode(replVector.begin(), replVector.end()); suffixSize=wc.wcwidth(0); } if (suffixSize < dls) { widecharbuf wc; wc.init_unicode(directoryW.begin(), lastSlash); directoryW=wc.get_unicode_truncated(dls-suffixSize, 0) .first; lastSlash=b=directoryW.begin(); e=directoryW.end(); for (c=b; c != e; ++c) { if (*c == '/') lastSlash=c; } } else { lastSlash=directoryW.begin(); } directoryW.erase(lastSlash, directoryW.end()); directoryW.insert(directoryW.end(), replVector.begin(), replVector.end()); } directoryName.setText(mail::iconvert::convert(directoryW, unicode_default_chset())); }
bool CursesMessageDisplay::processKeyInFocus(const Curses::Key &key) { CursesMessage *messageInfo=messageInfoPtr; if (!messageInfo) return false; if (key == key.ENTER) { size_t row; size_t col; std::string url; if (!messageInfo->getCurrentLink(row, col, url)) return true; if (url.substr(0, 7) == "mailto:") { if (myMessage::checkInterrupted(false) && (messageInfo=messageInfoPtr) != NULL) myMessage::newMessage(messageInfo->myfolder ->getFolder(), messageInfo->myfolder ->getServer(), url.substr(7)); return true; } std::string handler; size_t p=url.find(':'); if (p != std::string::npos) { handler=myServer::getConfigDir() + "/" + url.substr(0, p) + ".handler"; if (access(handler.c_str(), X_OK)) { handler=FILTERDIR "/" + url.substr(0, p) + ".handler"; if (access(handler.c_str(), X_OK)) handler=""; } } if (handler.size() == 0) { statusBar->clearstatus(); statusBar-> status(Gettext(_("Cannot find handler for %1%")) << url); statusBar->beepError(); return true; } pid_t pp=fork(); if (pp < 0) { statusBar->clearstatus(); statusBar->status(strerror(errno)); statusBar->beepError(); return true; } if (pp == 0) { close(1); open("/dev/null", O_WRONLY); dup2(1, 2); dup2(1, 0); execl(handler.c_str(), handler.c_str(), url.c_str(), (char *)NULL); exit(1); } pid_t p2; int waitstat; while ((p2=wait(&waitstat)) != pp) { if (p2 < 0 && errno != EINTR) break; } if (p2 == pp && WIFEXITED(waitstat) && WEXITSTATUS(waitstat) == 0) { statusBar->status(_("Started external handler.")); return true; } statusBar->clearstatus(); statusBar->status(_("External handler terminated with a non-zero exit code."), statusBar->SYSERROR); return true; } if (key == key_TAKEADDR) { mail::envelope *e=messageInfo->getEnvelope(); std::vector<mail::address> addrList; addrList.reserve(e->from.size() + e->to.size() + e->cc.size() + e->bcc.size() + e->sender.size() + e->replyto.size()); addrList.insert(addrList.end(), e->from.begin(), e->from.end()); addrList.insert(addrList.end(), e->to.begin(), e->to.end()); addrList.insert(addrList.end(), e->cc.begin(), e->cc.end()); addrList.insert(addrList.end(), e->bcc.begin(), e->bcc.end()); addrList.insert(addrList.end(), e->sender.begin(), e->sender.end()); addrList.insert(addrList.end(), e->replyto.begin(), e->replyto.end()); AddressBook::take(addrList); return true; } if (key == key_FOLDERINDEX || key == key_LESSTHAN) { keepgoing=false; myServer::nextScreen=&folderIndexScreen; myServer::nextScreenArg=messageInfo->myfolder; return true; } if (key == key_DELETE) messageInfo->myfolder->markDeleted( messageInfo->messagesortednum, true, false); if (key == key_UNDELETE) messageInfo->myfolder->markDeleted( messageInfo->messagesortednum, false, false); if (key == key_NEXTMESSAGE || key == key_DELETE || key == key_UNDELETE) { size_t dummy; if (messageInfo->myfolder->getNextMessage(dummy)) { Curses::keepgoing=false; myServer::nextScreen= &goNextMessage; myServer::nextScreenArg=messageInfo->myfolder; return true; } return true; } if (key == key_PREVMESSAGE) { size_t dummy; if (messageInfo->myfolder->getPrevMessage(dummy)) { Curses::keepgoing=false; myServer::nextScreen= &goPrevMessage; myServer::nextScreenArg=messageInfo->myfolder; } return true; } if (key == ' ' || key == Key::RIGHT || key == Key::PGDN || key == Key::DOWN) { if ((key == Key::DOWN || key == Key::RIGHT) && messageInfo->nextLink()) return true; // Went to next link instead size_t nLines=messageInfo->nLines(); size_t h=getHeight(); size_t lastLine= nLines > h ? nLines-h:0; size_t firstLineSaved=getFirstLineShown(); if (key == Key::DOWN || key == Key::RIGHT) setFirstLineShown(getFirstLineShown()+1); else setFirstLineShown(getFirstLineShown()+h); if (getFirstLineShown() > lastLine) setFirstLineShown(lastLine); if (firstLineSaved == getFirstLineShown() && key == ' ') { size_t dummy; if (messageInfo->myfolder-> getNextUnreadMessage(dummy)) { Curses::keepgoing=false; myServer::nextScreen= &goNextUnreadMessage; myServer::nextScreenArg=messageInfo->myfolder; return true; } statusBar->clearstatus(); statusBar->status(Gettext(_("No more unread mail in %1%")) << messageInfo->myfolder ->getFolder()->getName()); return true; } folderUpdated(); draw2(); messageInfo->toLastLink(); return true; } if (key == Key::LEFT || key == Key::PGUP || key == Key::UP) { if (key != Key::PGUP && messageInfo->prevLink()) return true; size_t h=key != Key::PGUP ? 1:getHeight(); setFirstLineShown(getFirstLineShown() < h ? 0: getFirstLineShown()-h); folderUpdated(); draw2(); return true; } if (key == key_VIEWATT) { Curses::keepgoing=false; myServer::nextScreen=showAttachments; myServer::nextScreenArg=messageInfo; return true; } if (key == key_SAVE) { std::string filename; { SaveDialog save_dialog(filename); save_dialog.requestFocus(); myServer::eventloop(); filename=save_dialog; mainScreen->erase(); } mainScreen->draw(); requestFocus(); if (messageInfoPtr.isDestroyed() || filename == "") return true; CursesAttachmentDisplay::downloadTo(messageInfoPtr, messageInfoPtr->shownMimeId != "" ? messageInfoPtr->structure .find(messageInfoPtr-> shownMimeId) :NULL, filename); return true; } if (key == key_BOUNCE) { if (messageInfo->shownMimeId.size()) { statusBar->clearstatus(); statusBar->status(_("Cannot forward only an attachment, just the whole message.")); statusBar->beepError(); return true; } mail::smtpInfo sendInfo; std::string from; std::string replyto; std::string fcc; std::string customheaders; if (!myMessage::getDefaultHeaders(messageInfo->myfolder ->getFolder(), messageInfo->myfolder ->getServer(), from, replyto, fcc, customheaders)) { return true; } { std::vector<mail::address> addrList; size_t errIndex; if (mail::address::fromString(from, addrList, errIndex) && addrList.size() > 0) sendInfo.sender=addrList[0].getAddr(); } mail::ptr<myFolder> folderPtr=messageInfo->myfolder; if (!CursesMessage::getBounceTo(sendInfo) || !CursesMessage::getSendInfo(Gettext(_("Blind-forward message to %1% address(es)? (Y/N) ")) << sendInfo.recipients .size(), "", sendInfo, NULL)) return true; disconnectCallbackStub disconnectStub; myServer::Callback sendCallback; mail::account *smtpServer; mail::folder *folder= CursesMessage::getSendFolder(sendInfo, smtpServer, NULL, disconnectStub); if (!folder) return true; if (folderPtr.isDestroyed() || messageInfoPtr.isDestroyed()) { delete folder; if (smtpServer) delete smtpServer; return true; } try { messageInfo->copyContentsTo(folder, sendCallback); bool rc=myServer::eventloop(sendCallback); delete folder; folder=NULL; if (smtpServer) { if (rc) { myServer::Callback disconnectCallback; disconnectCallback.noreport=true; smtpServer->logout(disconnectCallback); myServer:: eventloop(disconnectCallback); } delete smtpServer; smtpServer=NULL; } } catch (...) { if (folder) delete folder; if (smtpServer) delete smtpServer; LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); } return true; } if (key == key_REPLY) { mail::ptr<myFolder> folder=messageInfo->myfolder; if (myMessage::checkInterrupted() && !folder.isDestroyed() && !messageInfoPtr.isDestroyed()) messageInfo->reply(); return true; } if (key == key_FWD) { mail::ptr<myFolder> folder=messageInfo->myfolder; if (myMessage::checkInterrupted() && !folder.isDestroyed() && !messageInfoPtr.isDestroyed()) messageInfo->forward(); return true; } if (key == key_HEADERS) { erase(); messageInfo->fullEnvelopeHeaders= !messageInfo->fullEnvelopeHeaders; setFirstLineShown(0); messageInfo->beginReformat(getWidth()); folderUpdated(); return true; } if (key == key_PRINT) { mail::ptr<CursesMessage> ptr=messageInfo; int pipefd[2]; pid_t pid1; myServer::promptInfo printPrompt(_("Print to: ")); if (printCommand.size() == 0) printCommand="lpr"; printPrompt=myServer::prompt(printPrompt .initialValue(printCommand)); if (printPrompt.abortflag || ptr.isDestroyed()) return true; std::vector<const char *> args; { const char *p=getenv("SHELL"); if (!p || !*p) p="/bin/sh"; args.push_back(p); } args.push_back("-c"); printCommand=printPrompt; args.push_back(printCommand.c_str()); args.push_back(0); // // Fork a child process which writes the text image of the // message to a pipe. // // The parent process runs the print command, piping the text // into it. signal(SIGCHLD, SIG_DFL); if (pipe(pipefd) < 0) { statusBar->clearstatus(); statusBar->status(strerror(errno)); statusBar->beepError(); return true; } if ((pid1=fork()) == 0) { FILE *fp; // First child exits, the second child generates the // text. if (fork()) exit(0); signal(SIGPIPE, SIG_DFL); close(pipefd[0]); fp=fdopen(pipefd[1], "w"); if (fp) { size_t nLines=messageInfo->nLines(); size_t i; std::vector<std::pair<textAttributes, std::string> > line; std::vector<std::pair<textAttributes, std::string> > ::iterator b, e; for (i=0; i<nLines; i++) { messageInfo->getLineImage(i, line); for (b=line.begin(), e=line.end(); b != e; ++b) { fprintf(fp, "%s", b->second.c_str()); } fprintf(fp, "\n"); } fflush(fp); } exit(0); } // Wait for the first child to exit. if (pid1 < 0) { close(pipefd[0]); close(pipefd[1]); statusBar->clearstatus(); statusBar->status(strerror(errno)); statusBar->beepError(); return true; } close(pipefd[1]); while (wait(NULL) != pid1) ; Curses::runCommand(args, pipefd[0], ""); close(pipefd[0]); return true; } if (key == key_ROT13) { erase(); messageInfo->rot13=!messageInfo->rot13; setFirstLineShown(0); messageInfo->beginReformat(getWidth()); folderUpdated(); return true; } if ((key == key_UNENCRYPT) && (messageInfo->isSigned() || messageInfo->isEncrypted()) && GPG::gpg.gpg_installed()) { mail::ptr<CursesMessage> ptr=messageInfo; std::string passphrase; std::vector<std::string> options; bool wasEncrypted=messageInfo->isEncrypted(); if (wasEncrypted) { if (!PasswordList::passwordList.check("decrypt:", passphrase)) { myServer::promptInfo passPrompt(_("Passphrase (if" " required): ")); passPrompt=myServer::prompt(passPrompt .password()); if (passPrompt.abortflag || ptr.isDestroyed()) return true; passphrase=passPrompt; } } std::string::iterator b=GPG::gpg.extraDecryptVerifyOptions.begin(); while (b != GPG::gpg.extraDecryptVerifyOptions.end()) { if (unicode_isspace((unsigned char)*b)) { b++; continue; } std::string::iterator s=b; while (b != GPG::gpg.extraDecryptVerifyOptions.end()) { if (unicode_isspace((unsigned char)*b)) break; b++; } options.push_back(std::string(s, b)); } bool decryptFailed; if (messageInfo->decrypt(passphrase, options, decryptFailed)) { if (wasEncrypted && !decryptFailed) PasswordList::passwordList .save("decrypt:", passphrase); erase(); setFirstLineShown(0); messageInfo->beginReformat(getWidth()); folderUpdated(); if (wasEncrypted && decryptFailed) { statusBar->clearstatus(); statusBar->status(_("ERROR: Decryption failed," " passphrase forgotten.")); statusBar->beepError(); } } return true; } if (key == key_MSGSEARCH) { mail::ptr<CursesMessage> ptr=messageInfo; myServer::promptInfo searchPrompt(_("Search: ")); searchPrompt=myServer::prompt(searchPrompt .initialValue(searchString)); if (searchPrompt.abortflag || ptr.isDestroyed()) return true; searchString=searchPrompt; if (searchString.size() == 0) return true; mail::Search searchEngine; if (!searchEngine.setString(searchString, unicode_default_chset())) { statusBar->clearstatus(); statusBar->status(strerror(errno)); statusBar->beepError(); return true; } searchEngine.reset(); statusBar->clearstatus(); statusBar->status(_("Searching...")); statusBar->flush(); size_t n=messageInfo->nLines(); std::vector<std::pair<textAttributes, std::string> > line; while (firstLineToSearch < n) { messageInfo->getLineImage(firstLineToSearch, line); std::string s; std::vector<std::pair<textAttributes, std::string> > ::iterator b, e; for (b=line.begin(), e=line.end(); b != e; ++b) s += Gettext::toutf8(b->second); unicode_char *uc; size_t ucsize; if (unicode_convert_tou_tobuf(s.c_str(), s.size(), "utf-8", &uc, &ucsize, NULL)) { statusBar->clearstatus(); statusBar->status(strerror(errno)); statusBar->beepError(); return true; } if (ucsize == 0) { free(uc); ++firstLineToSearch; continue; } size_t i; for (i=0; i<ucsize; ++i) { searchEngine << uc[i]; } free(uc); searchEngine << (unicode_char)' '; // EOL if (searchEngine) { size_t nLines=messageInfo->nLines(); size_t h=getHeight(); size_t lastLine= nLines > h ? nLines-h:0; size_t foundAt=firstLineToSearch; size_t n=foundAt > 0 ? foundAt-1:0; if (n > lastLine) n=lastLine; setFirstLineShown(n); firstLineToSearch=foundAt+1; statusBar->clearstatus(); statusBar->status(Gettext(_("Text located," " displayed on" " line #%1%")) << (firstLineToSearch-n)); draw(); return true; } ++firstLineToSearch; } statusBar->clearstatus(); statusBar->status(_("Not found.")); return true; } if (key.fkey()) { std::string local_cmd; if (!CursesIndexDisplay::FilterMessageCallback ::getFilterCmd(key.fkeynum(), local_cmd)) return true; CursesIndexDisplay::FilterMessageCallback cb(local_cmd); std::vector<size_t> msgvec; msgvec.push_back(messageInfo->myfolder->getServerIndex (messageInfo->myfolder->getCurrentMessage())); messageInfo->myfolder->getServer() ->server->readMessageContent(msgvec, true, mail::readBoth, cb); if (myServer::eventloop(cb)) { cb.finish(); if (myServer::nextScreen) return true; if (cb.errmsg.size()) { statusBar->clearstatus(); statusBar->status(cb.errmsg); statusBar->beepError(); } } return true; } return false; }
std::string Gettext::fromutf8(std::string str) { return unicode::iconvert::convert(str, "utf-8", unicode_default_chset()); }
std::string Gettext::toutf8(std::string str) { return unicode::iconvert::convert(str, unicode_default_chset(), "utf-8"); }