/[winpt]/trunk/Src/wptFileManager.cpp
ViewVC logotype

Diff of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 195 by twoaday, Mon Apr 3 17:10:47 2006 UTC revision 217 by twoaday, Mon May 22 14:21:39 2006 UTC
# Line 18  Line 18 
18   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
19   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20   */   */
 /* TODO:  
  *    check_armor_type: we should check the whole file and not only the first line!  
  */  
21    
22  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
23  #include <config.h>  #include <config.h>
# Line 378  fm_get_file_type (const char *fname, int Line 375  fm_get_file_type (const char *fname, int
375  int  int
376  fm_build (listview_ctrl_t *lv, HWND ctrl)  fm_build (listview_ctrl_t *lv, HWND ctrl)
377  {  {
378      int i, rc = 0;      int i;
379      listview_ctrl_t c;      listview_ctrl_t c;
380      struct listview_column_s col[] = {      struct listview_column_s col[] = {
381          {0,  80, (char *)_("Status") },          {0,  80, (char *)_("Status") },
# Line 387  fm_build (listview_ctrl_t *lv, HWND ctrl Line 384  fm_build (listview_ctrl_t *lv, HWND ctrl
384          {0,   0, NULL}            {0,   0, NULL}  
385      };      };
386                    
387      rc = listview_new (&c);      listview_new (&c, ctrl);
     if (rc)  
         BUG (NULL);  
     c->ctrl = ctrl;  
388      for (i = 0; col[i].width; i++)      for (i = 0; col[i].width; i++)
389          listview_add_column (c, &col[i]);          listview_add_column (c, &col[i]);
390      listview_set_ext_style (c);      listview_set_ext_style (c);
# Line 413  fm_delete (listview_ctrl_t lv) Line 407  fm_delete (listview_ctrl_t lv)
407  int  int
408  fm_state_new (fm_state_t * ctx)  fm_state_new (fm_state_t * ctx)
409  {  {
     gpgme_error_t rc;  
410      fm_state_s *c;      fm_state_s *c;
411    
412      c = new fm_state_s;      c = new fm_state_s;
413      if (!c)      if (!c)
414          BUG (0);          BUG (0);
415      memset (c, 0, sizeof *c);      memset (c, 0, sizeof *c);
416      rc = gpgme_new (&c->ctx);      if (gpgme_new (&c->ctx))
     if (rc)  
417          BUG (0);          BUG (0);
418      *ctx = c;      *ctx = c;
419      return 0;      return 0;
# Line 602  fm_add_opened_files (listview_ctrl_t lv, Line 594  fm_add_opened_files (listview_ctrl_t lv,
594          else {          else {
595              char *p = make_filename (path, name, NULL);              char *p = make_filename (path, name, NULL);
596              rc = add_single_file (lv, p);              rc = add_single_file (lv, p);
597              free (p);              safe_free (p);
598          }          }
599          n++;          n++;
600      }      }
601      if (n == 1) /* single file selected. */      if (n == 1) /* single file selected. */
602          rc = add_single_file (lv, path);          rc = add_single_file (lv, path);
603      if (path)      safe_free (path);
         free (path);  
604      return rc;      return rc;
605  }  }
606    
607    
608  int  int
609  fm_assume_onepass_sig (const char * fname)  fm_assume_onepass_sig (const char *fname)
610  {  {    
     gpgme_data_t dat;  
611      armor_filter_context_t afx;      armor_filter_context_t afx;
612      gpg_iobuf_t fp;      gpg_iobuf_t fp;
613      PACKET * pkt = (PACKET *)calloc (1, sizeof *pkt);      gpgme_data_t dat;
614        PACKET *pkt;
615        char tmpfile[MAX_PATH+1];
616      int check = 0;      int check = 0;
617    
618        pkt = (PACKET *)calloc (1, sizeof *pkt);
619      if (!fname) {      if (!fname) {
620            get_temp_name (tmpfile, sizeof (tmpfile)-1, "gpgme.tmp");
621          gpg_data_new_from_clipboard (&dat, 0);          gpg_data_new_from_clipboard (&dat, 0);
622          gpg_data_release_and_set_file (dat, "gpgme.tmp");          gpg_data_release_and_set_file (dat, tmpfile);
623    
624          fp = gpg_iobuf_open ("gpgme.tmp");          fp = gpg_iobuf_open (tmpfile);
625          if (!fp)          if (!fp)
626              return 0;              return 0;
627          gpg_iobuf_ioctl (fp, 3, 1, NULL);          gpg_iobuf_ioctl (fp, 3, 1, NULL);
# Line 640  fm_assume_onepass_sig (const char * fnam Line 634  fm_assume_onepass_sig (const char * fnam
634              && pkt->pkttype == PKT_COMPRESSED)              && pkt->pkttype == PKT_COMPRESSED)
635              check = 1;                check = 1;  
636          gpg_free_packet (pkt);          gpg_free_packet (pkt);
         safe_free (pkt);  
637          gpg_iobuf_close (fp);          gpg_iobuf_close (fp);
638          remove ("gpgme.tmp");          remove (tmpfile);
639      }      }
640      /* XXX: implement it for real files */      /* XXX: implement it for real files */
641        safe_free (pkt);
642      return check;      return check;
643  }  }
644    
# Line 657  fm_get_current_pos (listview_ctrl_t lv) Line 651  fm_get_current_pos (listview_ctrl_t lv)
651      items = listview_count_items (lv, 0);      items = listview_count_items (lv, 0);
652      if (!items)      if (!items)
653          return -1;          return -1;
654      else if (items == 1)      else if (items == 1) {
     {  
655          listview_select_one (lv, 0);          listview_select_one (lv, 0);
656          return 0;          return 0;
657      }      }
658      else if (items > 1)      else if (items > 1) {
     {  
659          i = listview_get_curr_pos (lv);          i = listview_get_curr_pos (lv);
660          if (i == -1)          if (i == -1) {
661          {              msg_box (lv->ctrl, _("Please select a file."),
662              msg_box (lv->ctrl, _("Please select a file."), _("File Manager"), MB_ERR);                       _("File Manager"), MB_ERR);
663              return -1;              return -1;
664          }          }
665          return i;          return i;
666      }      }
667    
668      return -1;      return -1;
669  } /* fm_get_current_pos */  }
670    
671    
672  static int  static int
673  fm_check_detached_sig( listview_ctrl_t lv, int pos )  fm_check_detached_sig (listview_ctrl_t lv, int pos)
674  {  {
675      char type[128];      char type[128];
676    
677      listview_get_item_text( lv, pos, 0, type, 127 );      listview_get_item_text (lv, pos, 0, type, sizeof (type)-1);
678      return !strcmp( type, "SIGNED-DETACH" )? 1 : 0;      return !strcmp (type, "SIGNED-DETACH")? 1 : 0;
679  } /* fm_check_detached_sig */  }
680    
681    
682  int  int
# Line 741  fm_check_file_type (listview_ctrl_t lv, Line 733  fm_check_file_type (listview_ctrl_t lv,
733      }      }
734            
735      return rc;      return rc;
736  } /* fm_check_file_type */  }
737    
738    
739  /* Set the file status of the given command @fm_cmd.  /* Set the file status of the given command @fm_cmd.
# Line 812  fm_clearsign_8bit (listview_ctrl_t lv, f Line 804  fm_clearsign_8bit (listview_ctrl_t lv, f
804      if (!cnt)      if (!cnt)
805          return 0;          return 0;
806      n = -1;      n = -1;
807      i = log_box (_("File Manager"), MB_WARN|MB_YESNO,      i = log_box (_("File Manager"), MB_WARN|MB_YESNO,
808                   _("\"%s\" does not seems to be a text file.\n"                   _("\"%s\" does not seems to be a text file.\n"
809                     "Do you really want to clearsign it?"), name);                     "Do you really want to clearsign it?"), name);
810      if (i == IDYES)      if (i == IDYES)
# Line 820  fm_clearsign_8bit (listview_ctrl_t lv, f Line 812  fm_clearsign_8bit (listview_ctrl_t lv, f
812      return n;      return n;
813  }  }
814    
815    
816  int  int
817  fm_parse_files (listview_ctrl_t lv, HWND dlg, int cmd)  fm_parse_files (listview_ctrl_t lv, HWND dlg, int cmd)
818  {  {
# Line 1206  leave: Line 1199  leave:
1199  }  }
1200    
1201    
1202    char* get_pka_status (gpgme_signature_t sig);
1203    
1204    
1205  /* Show the human readable verify result from @sigres. */  /* Show the human readable verify result from @sigres. */
1206  static void  static void
1207  show_verify_result (gpgme_verify_result_t sigres)  show_verify_result (gpgme_verify_result_t sigres)
1208  {  {    
     gpgme_key_t key=NULL;  
1209      gpgme_signature_t sig=sigres->signatures;      gpgme_signature_t sig=sigres->signatures;
1210      const char *s, *keyid;      winpt_key_s key;
1211      int sigok = 0;      const char *s, *keyid, *uid;
1212      int type;      char *pka_info;
1213      char buf[384];      char buf[384];
1214        int sigok = 0;
1215    
1216      sig = sigres->signatures;      sig = sigres->signatures;
1217      sigok = sig->summary & GPGME_SIGSUM_GREEN;      sigok = sig->summary & GPGME_SIGSUM_GREEN;
1218      s = sigok? _("Good signature") : _("BAD signature");      s = sigok? _("Good signature") : _("BAD signature");
     type = sigok? MB_OK: MB_ICONWARNING|MB_OK;  
1219      keyid = sig->fpr;      keyid = sig->fpr;
1220      if (!keyid)      if (!keyid)
1221          return;          return;
1222        pka_info = get_pka_status (sig);
1223      keyid = strlen (sig->fpr) == 40? sig->fpr+32 : sig->fpr + 24;      keyid = get_keyid_from_fpr (sig->fpr);
1224      get_pubkey (sig->fpr, &key);      memset (&key, 0, sizeof (key));
1225        if (!winpt_get_pubkey (sig->fpr, &key))
1226            uid = key.ext->uids->uid;
1227        else
1228            uid = _("user ID not found");
1229      _snprintf (buf, sizeof (buf)-1, _("Signature made %s using %s key ID %s\n"      _snprintf (buf, sizeof (buf)-1, _("Signature made %s using %s key ID %s\n"
1230                                      "%s from \"%s\""),                                        "%s from \"%s\"\n%s"),
1231                  strtimestamp (sig->timestamp),                  strtimestamp (sig->timestamp),
1232                  get_key_pubalgo (sig->pubkey_algo),                  get_key_pubalgo (sig->pubkey_algo),
1233                  keyid, s, key? key->uids->uid : _("user ID not found"));                  keyid, s, uid, pka_info? pka_info : "");
1234      msg_box (NULL, buf, _("Decrypt Verify"), type);      msg_box (NULL, buf, _("Decrypt Verify"), sigok? MB_OK: MB_ICONWARNING|MB_OK);
1235        free_if_alloc (pka_info);
1236        winpt_release_pubkey (&key);
1237  }  }
1238    
1239    
1240  /* Check the recipients if we have at least one secret key. */  /* Check the recipients if we have at least one secret key. */
1241  bool  bool
1242  secret_key_available (gpgme_recipient_t rset)  is_seckey_available (gpgme_recipient_t rset)
1243  {  {
1244      gpgme_recipient_t r;      gpgme_recipient_t r;
1245      gpgme_key_t key;      winpt_key_s key;
1246    
1247      for (r=rset; r; r = r->next) {      for (r=rset; r; r = r->next) {
1248          if (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)          if (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)
1249              continue;              continue;
1250          else {          else {
1251                memset (&key, 0, sizeof (key));
1252              /* extra check to make sure the key is available right now. */              /* extra check to make sure the key is available right now. */
1253              if (!get_seckey (r->keyid, &key))              if (!winpt_get_seckey (r->keyid, &key)) {
1254                    winpt_release_pubkey (&key);
1255                  return true;                  return true;
1256                }
1257                winpt_release_pubkey (&key);
1258          }          }
1259      }      }
1260      return false;      return false;
# Line 1259  secret_key_available (gpgme_recipient_t Line 1264  secret_key_available (gpgme_recipient_t
1264  /* If the decrypt result contains the original file name,  /* If the decrypt result contains the original file name,
1265     we use it instead of the artificial "output - .gpg" string. */     we use it instead of the artificial "output - .gpg" string. */
1266  static int  static int
1267  restore_original_name (const char *output, const char *plaintext_filename)  restore_original_name (const char *output, const char *file_name)
1268  {  {
1269      char *dir;      char *dir;
1270      char *orig;      char *orig;
# Line 1267  restore_original_name (const char *outpu Line 1272  restore_original_name (const char *outpu
1272    
1273      dir = strrchr (output, '\\');      dir = strrchr (output, '\\');
1274      if (!dir)      if (!dir)
1275          orig = strdup (plaintext_filename);          orig = strdup (file_name);
1276      else {      else {
1277          orig = (char*)calloc (1, strlen (plaintext_filename)+ 1 +          orig = (char*)calloc (1, strlen (file_name)+ 1 +
1278                                   strlen (output)+1);                                   strlen (output)+1);
1279          if (!orig)          if (!orig)
1280              BUG (0);              BUG (0);
1281          memcpy (orig, output, (dir-output)+1);          memcpy (orig, output, (dir-output)+1);
1282          strcat (orig, plaintext_filename);          strcat (orig, file_name);
1283      }      }
1284        /* XXX: we need to find out if the string needs to be utf8 decoded. */
1285      if (overwrite_file (orig)) {      if (overwrite_file (orig)) {
1286          DeleteFile (orig);          DeleteFile (orig);
1287          if (!MoveFile (output, orig))          if (!MoveFile (output, orig))
# Line 1322  fm_decrypt (fm_state_t c, const char *na Line 1328  fm_decrypt (fm_state_t c, const char *na
1328              goto leave;              goto leave;
1329      }      }
1330    
1331        /* we fetch all recipients here to make sure they list is complete. */
1332        release_gpg_recipients (&c->pass_cb.recipients);
1333        gpg_get_recipients (name, &c->pass_cb.recipients);
1334    
1335      err = gpg_file_data_new (name, F_DATA_READ, &in);      err = gpg_file_data_new (name, F_DATA_READ, &in);
1336      if (err)      if (err)
1337          goto leave;          goto leave;
# Line 1329  fm_decrypt (fm_state_t c, const char *na Line 1339  fm_decrypt (fm_state_t c, const char *na
1339      err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);      err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1340      if (err)      if (err)
1341          goto leave;          goto leave;
1342        
1343      op_begin ();      op_begin ();
1344      err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);      err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);
1345      op_end ();      op_end ();
# Line 1341  fm_decrypt (fm_state_t c, const char *na Line 1351  fm_decrypt (fm_state_t c, const char *na
1351      }      }
1352    
1353      res = gpgme_op_decrypt_result (ctx);      res = gpgme_op_decrypt_result (ctx);
1354      if (res && res->recipients && !secret_key_available (res->recipients)) {      if (res && res->recipients && !is_seckey_available (res->recipients)) {
1355          const char *keyid = res->recipients->keyid;          const char *keyid = res->recipients->keyid;
1356          char *p = get_key_userid (keyid+8);          char *p = get_key_userid (keyid+8);
1357          gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;          gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;
# Line 1366  fm_decrypt (fm_state_t c, const char *na Line 1376  fm_decrypt (fm_state_t c, const char *na
1376          goto leave;          goto leave;
1377      }      }
1378      else if (res && res->file_name) {      else if (res && res->file_name) {
1379          char *file = strrchr (c->output, '\\');          char *file;
1380          int id = log_box (_("Decrypt"), MB_QUEST_ASK,          int id = IDNO;
1381    
1382            file = strrchr (c->output, '\\');
1383            if (!file)
1384                file = c->output;
1385            else
1386                file++;
1387            if (strcmp (res->file_name, file))
1388                id = log_box (_("Decrypt"), MB_QUEST_ASK,
1389                            _("The original file name is '%s'.\n\n"                            _("The original file name is '%s'.\n\n"
1390                              "Do you want to use this instead of '%s'?"),                              "Do you want to use this instead of '%s'?"),
1391                              res->file_name, file? file+1 : c->output);                        res->file_name, file);
1392          if (id == IDYES) {          if (id == IDYES) {
1393              /* before we can move the file, it needs to be closed first. */              /* before we can move the file, it needs to be closed first. */
1394              gpg_file_data_release (out);              gpg_file_data_release (out);
# Line 1380  fm_decrypt (fm_state_t c, const char *na Line 1398  fm_decrypt (fm_state_t c, const char *na
1398      }      }
1399      sigres = gpgme_op_verify_result (ctx);      sigres = gpgme_op_verify_result (ctx);
1400      if (sigres && sigres->signatures)      if (sigres && sigres->signatures)
1401          show_verify_result (sigres);              show_verify_result (sigres);
1402            
1403  leave:  leave:
1404      if (in)      if (in)
# Line 1456  leave: Line 1474  leave:
1474  static void  static void
1475  fm_add_sig_stat (file_sig_ctx_t log)  fm_add_sig_stat (file_sig_ctx_t log)
1476  {  {
1477      gpgme_key_t key;          struct winpt_key_s key;
1478      const char *kid;      const char *kid;
1479    
1480      kid = log->sig->fpr;      memset (&key, 0, sizeof (key));
1481      if (!kid)      kid = get_keyid_from_fpr (log->sig->fpr);
1482          BUG (NULL);      log->use_uid = 0;
1483      if (strlen (kid) == 40)      if (!winpt_get_pubkey (kid, &key)) {
1484          kid += 32;                log->user_id = key.ext->uids->uid;
     else if (strlen (kid) == 32)  
         kid += 24;  
     if (get_pubkey (kid, &key))  
         log->use_uid = 0;  
     else {  
         log->user_id = key->uids->uid;  
1485          log->use_uid = 1;          log->use_uid = 1;
1486      }      }
1487        winpt_release_pubkey (&key);
1488      file_verify_add_state (log);      file_verify_add_state (log);
1489  }  }
1490    
# Line 1561  get_output_file (fm_state_t c, const cha Line 1574  get_output_file (fm_state_t c, const cha
1574      else      else
1575          title = _("Selected Output File");          title = _("Selected Output File");
1576    
1577      if (strstr (name, ".sig")      if (stristr (name, ".sig") ||
1578          || strstr (name, ".asc")          stristr (name, ".asc") ||
1579          || strstr (name, ".gpg")) {          stristr (name, ".gpg")) {
1580          _snprintf (fname, sizeof (fname) - 1, "%s", name);          _snprintf (fname, sizeof (fname) - 1, "%s", name);
1581          fname[strlen (fname) - 4] = '\0';          fname[strlen (fname) - 4] = '\0';
1582          if (file_exist_check (fname) == 0 && detached)            if (file_exist_check (fname) == 0 && detached)  
# Line 1593  get_output_file (fm_state_t c, const cha Line 1606  get_output_file (fm_state_t c, const cha
1606      if (detached)      if (detached)
1607          c->sigmode = GPGME_SIG_MODE_DETACH;          c->sigmode = GPGME_SIG_MODE_DETACH;
1608      else {      else {
1609          if (strstr (name, ".asc"))          if (stristr (name, ".asc"))
1610              c->sigmode = GPGME_SIG_MODE_CLEAR;              c->sigmode = GPGME_SIG_MODE_CLEAR;
1611          else          else
1612              c->sigmode = GPGME_SIG_MODE_NORMAL;              c->sigmode = GPGME_SIG_MODE_NORMAL;
# Line 1615  fm_verify (fm_state_t c, int detached, c Line 1628  fm_verify (fm_state_t c, int detached, c
1628      file_data_t in=NULL, out=NULL;      file_data_t in=NULL, out=NULL;
1629      int rc = 0;      int rc = 0;
1630    
1631      if (strstr (name, ".sig"))      if (stristr (name, ".sig"))
1632          detached = 1;          detached = 1;
1633    
1634      if (get_output_file (c, name, detached))      if (get_output_file (c, name, detached))
# Line 1709  leave: Line 1722  leave:
1722  /* Export the selected keys from the File Manager to a file. */  /* Export the selected keys from the File Manager to a file. */
1723  int  int
1724  fm_export (fm_state_t c)  fm_export (fm_state_t c)
1725  {  {    
     int rc = 0;  
1726      gpgme_ctx_t ctx = c->ctx;      gpgme_ctx_t ctx = c->ctx;
1727      gpgme_error_t err;      gpgme_error_t err;
1728      gpgme_key_t *rset = c->recp;      gpgme_key_t *rset = c->recp;
1729      file_data_t keydata = NULL;      file_data_t keydata = NULL;
1730      const char *name;      const char *name;
1731      char *p = NULL, *patt = NULL;      char *p = NULL, *patt = NULL;
1732        int rc = 0;
1733    
1734      if (!rset || !rset[0]) {      if (!rset || !rset[0]) {
1735          msg_box (c->dlg, _("No key was selected for export."), _("Export"), MB_ERR);          msg_box (c->dlg, _("No key was selected for export."), _("Export"), MB_ERR);
# Line 1751  fm_export (fm_state_t c) Line 1764  fm_export (fm_state_t c)
1764  leave:  leave:
1765      if (keydata)      if (keydata)
1766          gpg_file_data_release (keydata);          gpg_file_data_release (keydata);
1767      if (patt)      safe_free (patt);
         free (patt);  
1768      free_if_alloc (p);      free_if_alloc (p);
1769      return rc;      return rc;
1770  }  }
# Line 1845  int Line 1857  int
1857  fm_encrypt_into_zip (fm_state_t ctx, listview_ctrl_t lv)  fm_encrypt_into_zip (fm_state_t ctx, listview_ctrl_t lv)
1858  {  {
1859      PK_FILE_LIST list=NULL;      PK_FILE_LIST list=NULL;
1860      const char *outfile;      const char *outfile, *ext;
1861      char *out_enc;      char *out_enc;
1862      int nitems = listview_count_items (lv, 0);      int nitems;
1863      int i, idx = -1;      int i, idx = -1;
1864      int rc;      int rc;
1865    
1866        nitems = listview_count_items (lv, 0);
1867      if (!nitems) {      if (!nitems) {
1868          msg_box (NULL, _("Encrypting into a ZIP archive makes sense with multiple files"),          msg_box (NULL, _("Encrypting into a ZIP archive makes sense with multiple files"),
1869                   _("File Manager"), MB_ERR);                   _("File Manager"), MB_ERR);
# Line 1880  fm_encrypt_into_zip (fm_state_t ctx, lis Line 1893  fm_encrypt_into_zip (fm_state_t ctx, lis
1893      if (rc)      if (rc)
1894          return rc;          return rc;
1895    
1896      out_enc = make_filename (NULL, outfile, "gpg");      ext = file_get_extension (ctx->ctx, ctx->sigmode)+1;
1897        out_enc = make_filename (NULL, outfile, ext);
1898      fm_set_status (lv, idx, FM_ENCRYPT, (gpgme_sig_mode_t)0, 1, out_enc);      fm_set_status (lv, idx, FM_ENCRYPT, (gpgme_sig_mode_t)0, 1, out_enc);
1899      free_if_alloc (out_enc);      free_if_alloc (out_enc);
1900    
# Line 1955  fm_cmp_cb (LPARAM first, LPARAM second, Line 1969  fm_cmp_cb (LPARAM first, LPARAM second,
1969      const char *a = 0;      const char *a = 0;
1970      const char *b = 0;      const char *b = 0;
1971    
1972      switch( (int)sortby ) {      switch ((int)sortby) {
1973      case FM_SORT_STAT:      case FM_SORT_STAT:
1974          break;          break;
1975      case FM_SORT_NAME:      case FM_SORT_NAME:
# Line 1971  fm_cmp_cb (LPARAM first, LPARAM second, Line 1985  fm_cmp_cb (LPARAM first, LPARAM second,
1985  int  int
1986  fm_sort (listview_ctrl_t lv, int sortby)  fm_sort (listview_ctrl_t lv, int sortby)
1987  {  {
1988      return listview_sort_items( lv, sortby, fm_cmp_cb );      return listview_sort_items (lv, sortby, fm_cmp_cb);
1989  }  }
1990    
1991    

Legend:
Removed from v.195  
changed lines
  Added in v.217

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26